【问题标题】:Inheriting properties from model - Navigation properties can only participate in a single relationship从模型继承属性 - 导航属性只能参与单个关系
【发布时间】:2020-12-10 01:05:23
【问题描述】:

我正在尝试通过使用多个继承级别与多个实体共享公共属性,但我遇到了错误。

无法在“User.SupersCreated”和“Super.CreatedBy”之间创建关系,因为“User.BasicsCreated”和“Basic.CreatedBy”之间已经存在关系。导航属性只能参与单个关系。如果您想在“OnModelCreating”中首先在导航“Super.CreatedBy”上覆盖现有关系调用“Ignore”。

我的模型结构如下。

public class EntityBase
{
    public Guid Id { get; set; }
    public Guid CreatedById { get; set; }
    public User CreatedBy { get; set; }
}

public class Basic: EntityBase
{
    public string BasicProperty { get; set; }
}

public class Super : Basic
{
    public string SuperProperty { get; set; }
}

public class User : IdentityUser<Guid>
{
    public ICollection<Basic> BasicsCreated { get; set; }
    public ICollection<Super> SupersCreated { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<User>()
        .HasMany(x => x.BasicsCreated)
        .WithOne(x => x.CreatedBy);

    modelBuilder.Entity<User>()
        .HasMany(x => x.SupersCreated)
        .WithOne(x => x.CreatedBy);
}

问题似乎是Super 继承自Basic 的结果,或者至少,当我删除此级别的继承并使Super 继承自EntityBase 时,问题就消失了(但是比我'将丢失Basic 中存在的属性。

谁能帮我理解为什么我会收到这个错误以及应该做些什么来解决它?


编辑

在考虑了更多之后,我认为我试图滥用继承来做它不打算做的事情。

我希望最终得到的数据库结构是:

尽管我的Basic 和Super 表共享相同的属性,而Super 有它自己的附加属性,Basic 数据和Super 数据之间没有任何关系。

查看Microsoft's tutorial on implementing inheritance,有两种选择:

  • 每种类型的表
  • 每个层次结构的表

这些都不是我想要实现的目标。

也许我应该使用接口来定义存在于不相关实体之间的公共属性。看来我还是需要支持并重新评估我的设计。

【问题讨论】:

    标签: c# inheritance entity-framework-core ef-code-first


    【解决方案1】:

    如果实体的某些基类被标识为实体(如您的 Super 和 Basic),默认情况下 EF Core 将尝试使用其中一种数据库继承策略。

    如果你不想这样(想要对待就像非实体基类一样),那么你必须在 OnModelCreating 的开头显式配置它,例如为您的样品

    modelBuilder.Entity<Super>().HasBaseType((Type)null);
    

    或更一般地使用类似于此的循环

    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
        entityType.BaseType = null;
    

    然后在需要时明确定义实体层次结构。

    【讨论】:

    • 太棒了,这允许在应用程序层和数据库层中的继承之间断开连接(无论这被视为好事还是坏事是另一回事)。谢谢伊万!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 2016-01-08
    相关资源
    最近更新 更多