对你而言,Item
应该有2个导航属性。一个用于链接的项目,另一个用于链接的项目。
public class Item
{
public virtual ICollection<ItemAssociation> AssociatedItems { get; set; }
public virtual ICollection<ItemAssociation> ItemsAssociatedThisItem { get; set; }
}
public class ItemAssociation
{
public int ItemId { get; set; }
public int ItemAssociatedId { get; set; }
public virtual Item Item { get; set; }
public virtual Item ItemAssociated { get; set; }
}
映射:
modelBuilder.Entity<ItemAssociation>()
.HasKey(i => new {i.ItemId , i.ItemAssociatedId });
modelBuilder.Entity<Item>()
.HasMany(i => i.AssociatedItems)
.WithRequired(i => i.ItemAssociated)
.HasForeignKey(i => i.ItemAssociatedId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Item>()
.HasMany(i => i.ItemsAssociatedThisItem)
.WithRequired(i => i.Item)
.HasForeignKey(i => i.ItemId)
.WillCascadeOnDelete(false);
当你想要检索与特定项目的所有项目,你会得到两个集合,CONCAT他们并删除重复值。
EDIT
无关联实体映射:
类别:
public class Item
{
public int ItemId { get; set; }
public virtual ICollection<Item> AssociatedItems { get; set; }
public virtual ICollection<Item> ItemsAssociatedThisItem { get; set; }
}
映射:
modelBuilder.Entity<Item>()
.HasMany(i => i.AssociatedItems)
.WithMany(i=> i.ItemsAssociatedThisItem)
.Map(i =>
{
i.MapRightKey("ItemId");
i.MapLeftKey("AssociatedItemId");
i.ToTable("ItemsAssociation");
});
生成迁移:
CreateTable(
"dbo.Items",
c => new
{
ItemId = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.ItemId);
CreateTable(
"dbo.ItemsAssociation",
c => new
{
AssociatedItemId = c.Int(nullable: false),
ItemId = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.AssociatedItemId, t.ItemId })
.ForeignKey("dbo.Items", t => t.AssociatedItemId)
.ForeignKey("dbo.Items", t => t.ItemId)
.Index(t => t.AssociatedItemId)
.Index(t => t.ItemId);
我觉得现在比较干净。只是根据你的风格改变名称
添加一个关联实体根本不能解决问题,这让我觉得它更加复杂。 –
一个'Item'可以链接到多个'Item',对吧?项目A链接到B和C.项目B链接到D和A(由于前面的链接)。所以,我相信唯一可以做到这一点的方法是使用关联实体。另外,要做出“反身关系”,实体需要2个集合......每个集合都有一个集合。看看这个线程,它可能是有用的http://stackoverflow.com/questions/31461173/entity-framework-fluent-api-create-table-with-2-fk/31465908#31465908 –
你正在描述古典很多我熟悉的很多关系。我提出的用例在逻辑上只需要一个集合,问题在于是否可以用EF完成一个集合。 并且不,您不必为多对多关系设置关联实体。 EF可以为你做这件事 - 当然在数据库中会有一个关联表,但它会隐藏在模型中。 –