从模型继承属性 - 导航属性只能参与单一关系
Inheriting properties from model - Navigation properties can only participate in a single relationship
我试图通过使用多级继承与多个实体共享公共属性,但我 运行 遇到了错误。
Cannot create a relationship between 'User.SupersCreated' and 'Super.CreatedBy' because a relationship already exists between 'User.BasicsCreated' and 'Basic.CreatedBy'. Navigation properties can only participate in a single relationship. If you want to override an existing relationship call 'Ignore' on the navigation 'Super.CreatedBy' first in 'OnModelCreating'.
我的模型结构如下。
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来看,有两个选择:
- Table 每种类型
- Table 每个层级
这些都不是我要实现的目标。
也许我应该使用接口来定义 不相关 实体之间存在的公共属性。看来我需要重新评估我的设计了。
如果实体的某些基础 classes 被标识为实体(与您的 Super
和 Basic
一样),默认情况下 EF Core 将尝试使用以下方法之一数据库继承策略。
如果你不想要那个(想要处理就像非实体基础 class),那么你必须在 OnModelCreating
的最开始明确配置它,例如为你的样品
modelBuilder.Entity<Super>().HasBaseType((Type)null);
或更普遍地使用与此类似的循环
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
entityType.BaseType = null;
然后在需要时明确定义实体层次结构。
我试图通过使用多级继承与多个实体共享公共属性,但我 运行 遇到了错误。
Cannot create a relationship between 'User.SupersCreated' and 'Super.CreatedBy' because a relationship already exists between 'User.BasicsCreated' and 'Basic.CreatedBy'. Navigation properties can only participate in a single relationship. If you want to override an existing relationship call 'Ignore' on the navigation 'Super.CreatedBy' first in 'OnModelCreating'.
我的模型结构如下。
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来看,有两个选择:
- Table 每种类型
- Table 每个层级
这些都不是我要实现的目标。
也许我应该使用接口来定义 不相关 实体之间存在的公共属性。看来我需要重新评估我的设计了。
如果实体的某些基础 classes 被标识为实体(与您的 Super
和 Basic
一样),默认情况下 EF Core 将尝试使用以下方法之一数据库继承策略。
如果你不想要那个(想要处理就像非实体基础 class),那么你必须在 OnModelCreating
的最开始明确配置它,例如为你的样品
modelBuilder.Entity<Super>().HasBaseType((Type)null);
或更普遍地使用与此类似的循环
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
entityType.BaseType = null;
然后在需要时明确定义实体层次结构。