【发布时间】:2023-03-07 17:17:01
【问题描述】:
想象这个类用于实体框架的数据模型:
public class CriteriaCatalogue : BaseDataModel
{
public string Name { get; set; }
public List<CriterionToCriteriaCatalogueLink> CriteriaLinks { get; set; }
public virtual ICollection<CriteriaCatalogueToCriteriaCatalogueLink> CatalogueChildren { get; set; }
public virtual ICollection<CriteriaCatalogueToCriteriaCatalogueLink> CatalogueParents { get; set; }
// a bunch of additional properties with custom getters and setters to more easily access and create the child/parent `CriteriaCatalogue`s
}
CriteriaLinks 属性被完美填充,但我的父子列表链接到相同类型根本不起作用,它们填充了相同的对象(因此在查看 Owner1 时,两个子项都将是 Owner1父母将是 Owner1)
因此,虽然以下代码是有效代码,并且只要您不让 EF 触摸它就会按预期工作,但 EF 将删除其中一个连接:
CriteriaCatalogue owned = new CriteriaCatalogue { Name = "Owned" };
CriteriaCatalogue owner1 = new CriteriaCatalogue { Name = "Owner1", CriteriaCatalogues = new List<CriteriaCatalogue> { owned } };
CriteriaCatalogue owner2 = new CriteriaCatalogue { Name = "Owner2", CriteriaCatalogues = new List<CriteriaCatalogue> { owned } };
如果通过 EF 将所有三个对象保存到数据库中,结果如下:
owned 没有任何孩子或父母。
owner1 将 owner1 作为孩子,将 owner1 作为父母。
owner2 拥有 owner2 作为孩子,拥有 owner2 作为父母。
如何正确配置 EF 以允许 owned 可以属于多个其他实体?
编辑 2:我让它工作了。我需要做的就是在 OnModelCreating 方法中切换 CatalogueChildren 和 CatalogueParents 引用:
modelBuilder.Entity<CriteriaCatalogueToCriteriaCatalogueLink>(cctcc =>
{
cctcc.HasKey(cctcc => new { cctcc.ChildId, cctcc.ParentId });
cctcc.HasOne(cctcc => cctcc.Child)
.WithMany(children => children.CatalogueParents)
.HasForeignKey(cctcc => cctcc.ChildId)
.OnDelete(DeleteBehavior.ClientSetNull);
cctcc.HasOne(cctcc => cctcc.Parent)
.WithMany(parents => parents.CatalogueChildren)
.HasForeignKey(cctcc => cctcc.ParentId);
});
编辑:根据 Sergey 的回答,这是我的完整实现:
链接类:
public class CriteriaCatalogueToCriteriaCatalogueLink
{
public Guid ParentId { get; set; }
public virtual CriteriaCatalogue Parent { get; set; }
public Guid ChildId { get; set; }
public virtual CriteriaCatalogue Child { get; set; }
}
DbContext.OnModelCreating sn-p:
modelBuilder.Entity<CriteriaCatalogue>(criterionCatalogue =>
{
criterionCatalogue.HasMany(cc => cc.CriteriaLinks);
criterionCatalogue.HasMany(cc => cc.CatalogueChildren);
criterionCatalogue.HasMany(cc => cc.CatalogueParents);
});
modelBuilder.Entity<CriterionToCriteriaCatalogueLink>(ctcc =>
{
ctcc.HasKey(ctcc => new { ctcc.CriteriaCatalogueId, ctcc.CriterionId });
ctcc.HasOne(ctcc => ctcc.Criterion)
.WithMany(criterion => criterion.CriteriaCatalogueLinks)
.HasForeignKey(ctcc => ctcc.CriterionId);
ctcc.HasOne(ctcc => ctcc.CriteriaCatalogue)
.WithMany(criteriaCatalogue => criteriaCatalogue.CriteriaLinks)
.HasForeignKey(ctcc => ctcc.CriteriaCatalogueId);
});
modelBuilder.Entity<CriteriaCatalogueToCriteriaCatalogueLink>(cctcc =>
{
cctcc.HasKey(cctcc => new { cctcc.ChildId, cctcc.ParentId });
cctcc.HasOne(cctcc => cctcc.Child)
.WithMany(children => children.CatalogueChildren)
.HasForeignKey(cctcc => cctcc.ChildId)
.OnDelete(DeleteBehavior.ClientSetNull);
cctcc.HasOne(cctcc => cctcc.Parent)
.WithMany(parents => parents.CatalogueParents)
.HasForeignKey(cctcc => cctcc.ParentId);
});
如您所见,连接Criterions 的实现有点不同,但基本相同。我尝试了完全相同的方法来连接CriteriaCatalogues,但它不起作用。我认为当我尝试这样做时,EF 给了我一个关于圆圈引用的错误。最重要的是,一个CriteriaCatalogue 仍然不可能有多个父母。
【问题讨论】:
-
很抱歉,我对 google 的内容没有任何想法,我确信这只是 EF 模型中的一个选项。
-
我对您的示例有疑问,在调用
SaveChanges之后,objectA.Id是1还是2?子对象不能同时有两个父对象。 -
在这种情况下,ID 并不重要。无论如何,它们都是随机生成的 GUID。而且,关于它是否可能,它肯定是。我只需要弄清楚如何设置 EF 来处理它。正如您在我的实现中看到的,我已经设置了一个 Linking 类(所以从技术上讲,是的,一个子对象没有两个直接的父对象,但我们可以设置一个基本实现相同的模型)
-
您将一个对象作为子对象引用到其他两个父对象。保存数据后,显示插入 2 条记录,但在代码中,有两个
GUID分配给Id属性,这些记录与一个对象相关。如果你删除objectA,那么objectB的子对象会被删除,或者objectC或者EF应该删除数据库中的两行来删除一个对象? -
这个例子可能有点混乱,因为我使用该属性的设置器(
CriteriaCatalogues)来创建链接对象,并将它们存储在单独的列表中(例如CatalogueChildren),并且 getter 只公开CriteriaCatalogues 的列表而不是链接对象的列表
标签: c# entity-framework .net-core entity-framework-core