lme*_*213 2 c# asp.net entity-framework entity-framework-core .net-core
我试图描述与 Entity Framework Core 2 的多对多自引用关系。本质上,我试图建模的是一种树结构,其中每个元素可以有任意数量的父元素和子元素(所以我猜更多的是图而不是树)。这是我到目前为止所拥有的:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试生成初始迁移时,我得到以下信息:
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'.
我假设这意味着对于连接表,它试图将两列命名为相同的东西,因为它们引用了同一个表。
此外,我真的不知道如何连接OrgLevel
模型中的最后两个导航属性,以便它们使用连接表来解析。
任何帮助,将不胜感激!
主要问题是以下流畅的配置:
builder.Entity<OrgLevelOrgLevels>()
.HasKey(t => new { t.ParentOrgLevel, t.ChildOrgLevel });
Run Code Online (Sandbox Code Playgroud)
错误消息有点误导。此重载需要原始属性(显式或阴影),但您传递的是导航属性。
有几种方法可以解决它。
首先,向模型添加显式 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; }
}
Run Code Online (Sandbox Code Playgroud)
并使用
builder.Entity<OrgLevelOrgLevels>()
.HasKey(t => new { t.ParentOrgLevelId, t.ChildOrgLevelId });
Run Code Online (Sandbox Code Playgroud)
另一种方法是保持模型不变,但使用另一个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");
Run Code Online (Sandbox Code Playgroud)
当然,您可以提前明确定义它们:
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);
Run Code Online (Sandbox Code Playgroud)
请注意,此模型引入了多个级联路径,因此您需要关闭至少两个关系之一的级联删除并手动处理它。
归档时间: |
|
查看次数: |
1789 次 |
最近记录: |