我添加一个例子InversePropertyAttribute
。它不仅可用于自引用实体中的关系(如拉迪斯拉夫答案中链接的示例),还可用于不同实体之间关系的“正常”情况:
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;}
}
这将描述与此 Fluent Code 相同的关系:
modelBuilder.Entity<Book>()
.HasOptional(b => b.Author)
.WithMany(a => a.Books);
... 或者 ...
modelBuilder.Entity<Author>()
.HasMany(a => a.Books)
.WithOptional(b => b.Author);
现在,添加InverseProperty
上面示例中的属性是多余的:映射约定将创建相同的单一关系 anyway.
但考虑这个例子(一个图书库,只包含两位作者一起写的书):
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;}
}
映射约定不会检测这些关系的哪一端属于在一起并实际创建四种关系(Books 表中有四个外键)。在这种情况下使用InverseProperty
将有助于在模型中定义我们想要的正确关系:
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;}
}
在这里我们只能得到两种关系。 (注:InverseProperty
属性仅在关系的一端是必需的,我们可以省略另一端的属性。)