[英]EF Core Many-to-Many self join
I am trying to describe a many-to-many self-referential relationship to Entity Framework Core 2. Essentially what I'm trying to model is a sort of tree structure, in which each element can have an arbitrary number of parent and child elements (so I guess more a graph than a tree). 我试图描述与Entity Framework Core 2的多对多自引用关系。本质上,我要建模的是一种树结构,其中每个元素可以具有任意数量的父元素和子元素(所以我猜想更多的是图形而不是树)。 Here's what I have so far: 这是我到目前为止的内容:
public class OrgLevel
{
...
public ICollection<OrgLevelOrgLevels> OrgLevelOrgLevelsAsParent { get; set; }
public ICollection<OrgLevelOrgLevels> OrgLevelOrgLevelsAsChild { get; set; }
public ICollection<OrgLevel> ParentOrganizationStructureLevels { get; set; }
public ICollection<OrgLevel> ChildOrganizationStructureLevels { get; set; }
}
public class OrgLevelOrgLevels
{
public OrgLevel ParentOrgLevel { get; set; }
public OrgLevel ChildOrgLevel { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
...
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<OrgLevelOrgLevels>()
.HasKey(t => new { t.ParentOrgLevel, t.ChildOrgLevel });
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ChildOrgLevel)
.WithMany(col => col.OrgLevelOrgLevelsAsChild);
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ParentOrgLevel)
.WithMany(pol => pol.OrgLevelOrgLevelsAsParent);
}
}
When i try to generate the initial migration, i get the following: 当我尝试生成初始迁移时,得到以下信息:
The navigation property 'ChildOrgLevel' cannot be added to the entity type 'OrgLevelOrgLevels' because a property with the same name already exists on entity type 'OrgLevelOrgLevels'.
I am assuming this means that for the join table, it's trying to name both columns the same thing as they reference the same table. 我假设这意味着对于联接表,它试图为两列引用相同的表而命名。
Additionally, I don't really have any idea how to wire the last two navigation properties in the OrgLevel
model so that they will use the join table to resolve. 另外,我真的不知道如何在OrgLevel
模型中连接最后两个导航属性,以便它们将使用OrgLevel
表来进行解析。
Any help would be appreciated! 任何帮助,将不胜感激!
The main issue is the following fluent configuration: 主要问题是以下流畅的配置:
builder.Entity<OrgLevelOrgLevels>()
.HasKey(t => new { t.ParentOrgLevel, t.ChildOrgLevel });
The error message is kind of misleading. 该错误消息有点误导。 This overload expects primitive properties (either explicit or shadow ), but you are passing navigation properties . 此重载需要原始属性(显式或阴影 ),但是您正在传递导航属性 。
There are several ways to resolve it. 有几种解决方法。
First, add explicit FK properties to the model (assuming referenced PK property type is int
): 首先,向模型添加显式的FK属性(假设引用的PK属性类型为int
):
public class OrgLevelOrgLevels
{
public int ParentOrgLevelId { get; set; }
public OrgLevel ParentOrgLevel { get; set; }
public int ChildOrgLevelId { get; set; }
public OrgLevel ChildOrgLevel { get; set; }
}
and use 和使用
builder.Entity<OrgLevelOrgLevels>()
.HasKey(t => new { t.ParentOrgLevelId, t.ChildOrgLevelId });
Another way is to keep the model as is, but use another HasKey
overload and pass shadow property names after they are defined: 另一种方法是保持模型不变,但使用另一个HasKey
重载并在定义它们后传递阴影属性名称:
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ChildOrgLevel)
.WithMany(col => col.OrgLevelOrgLevelsAsChild)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ParentOrgLevel)
.WithMany(pol => pol.OrgLevelOrgLevelsAsParent);
builder.Entity<OrgLevelOrgLevels>()
.HasKey("ParentOrgLevelId", "ChildOrgLevelId");
Of course you can define them explicitly in advance: 当然,您可以预先明确定义它们:
builder.Entity<OrgLevelOrgLevels>()
.Property<int>("ParentOrgLevelId");
builder.Entity<OrgLevelOrgLevels>()
.Property<int>("ChildOrgLevelId");
builder.Entity<OrgLevelOrgLevels>()
.HasKey("ParentOrgLevelId", "ChildOrgLevelId");
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ChildOrgLevel)
.WithMany(col => col.OrgLevelOrgLevelsAsChild)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity<OrgLevelOrgLevels>().HasOne(olol => olol.ParentOrgLevel)
.WithMany(pol => pol.OrgLevelOrgLevelsAsParent);
Note that this model introduces multiple cascade paths, so you need to turn cascade delete off at least of one of the two relationships and handle it manually. 请注意,此模型引入了多个级联路径,因此您需要关闭级联删除,至少要关闭两个关系之一,然后手动进行处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.