Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 4.1 InverseProperty Attribute

Just wanted to know more about RelatedTo attribute and I found out it has been replaced by ForeignKey and InverseProperty attributes in EF 4.1 RC.

Does anyone know any useful resources about the scenarios that this attribute becomes useful?

Should I use this attribute on navigation properties? example:

public class Book {   public int ID {get; set;}   public string Title {get; set;}    [ForeignKey("FK_AuthorID")]   public Author Author {get; set;} }    public class Author {   public int ID {get; set;}   public string Name {get; set;}   // Should I use InverseProperty on the following property?   public virtual ICollection<Book> Books {get; set;} } 
like image 837
Kamyar Avatar asked Apr 19 '11 12:04

Kamyar


2 Answers

I add an example for the InversePropertyAttribute. It cannot only be used for relationships in self referencing entities (as in the example linked in Ladislav's answer) but also in the "normal" case of relationships between different entities:

public class Book {     public int ID {get; set;}     public string Title {get; set;}      [InverseProperty("Books")]     public Author Author {get; set;} }  public class Author {     public int ID {get; set;}     public string Name {get; set;}      [InverseProperty("Author")]     public virtual ICollection<Book> Books {get; set;} } 

This would describe the same relationship as this Fluent Code:

modelBuilder.Entity<Book>()             .HasOptional(b => b.Author)             .WithMany(a => a.Books); 

... or ...

modelBuilder.Entity<Author>()             .HasMany(a => a.Books)             .WithOptional(b => b.Author); 

Now, adding the InverseProperty attribute in the example above is redundant: The mapping conventions would create the same single relationship anyway.

But consider this example (of a book library which only contains books written together by two authors):

public class Book {     public int ID {get; set;}     public string Title {get; set;}      public Author FirstAuthor {get; set;}     public Author SecondAuthor {get; set;} }  public class Author {     public int ID {get; set;}     public string Name {get; set;}      public virtual ICollection<Book> BooksAsFirstAuthor {get; set;}     public virtual ICollection<Book> BooksAsSecondAuthor {get; set;} } 

The mapping conventions would not detect which ends of these relationships belong together and actually create four relationships (with four foreign keys in the Books table). In this situation using the InverseProperty would help to define the correct relationships we want in our model:

public class Book {     public int ID {get; set;}     public string Title {get; set;}      [InverseProperty("BooksAsFirstAuthor")]     public Author FirstAuthor {get; set;}     [InverseProperty("BooksAsSecondAuthor")]     public Author SecondAuthor {get; set;} }  public class Author {     public int ID {get; set;}     public string Name {get; set;}      [InverseProperty("FirstAuthor")]     public virtual ICollection<Book> BooksAsFirstAuthor {get; set;}     [InverseProperty("SecondAuthor")]     public virtual ICollection<Book> BooksAsSecondAuthor {get; set;} } 

Here we would only get two relationships. (Note: The InverseProperty attribute is only necessary on one end of the relationship, we can omit the attribute on the other end.)

like image 140
Slauma Avatar answered Oct 08 '22 10:10

Slauma


ForeignKey attribute pairs FK property with navigation property. It can be placed either on FK property or navigation property. It is equivalent of HasForeignKey fluent mapping.

public class MyEntity {     public int Id { get; set; }      [ForeignKey("Navigation")]     public virtual int NavigationFK { get; set; }      public virtual OtherEntity Navigation { get; set; } } 

InverseProperty is used for defining self referencing relation and pairing navigation properties on both ends. Check this question for sample.

like image 36
Ladislav Mrnka Avatar answered Oct 08 '22 12:10

Ladislav Mrnka