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.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…