如何解决"导航属性只能参与单一关系。"以下案例有错误吗?
1公司有许多Milestone和MissionValueStory,其中Milestone和MissionValueStory共享相同的表,具有不同的typeId,并且每个都有很多翻译,只与companyInfoId链接
或者更好地打破了公司信息与公司之间的关系,只是另一个获取companyInfo的查询很容易?
public class Company
{
[key]
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<CompanyInfo> Milestone { get; set; } //multi
public virtual ICollection<CompanyInfo> MissionValueStory { get; set; } //multi
}
public class CompanyInfo
{
[key]
public long Id { get; set; }
public long typeId { get; set; }
[Required]
public long CompanyId { get; set; }
public string Title { get; set; }
public string Text { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
public ICollection<Translation> Translation { get; set; }
}
public class Translation
{
[key]
public long Id { get; set; }
public string Title { get; set; }
[Required]
public long CompanyInfoId { get; set; }
public string Language { get; set; }
[ForeignKey("CompanyInfoId")]
public virtual CompanyInfo CompanyInfo { get; set; }
}
modelBuilder.Entity<Company>()
.HasMany(e => e.Milestone)
.WithOne(t => t.Company)
.HasForeignKey(m => m.CompanyId).IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Company>()
.HasMany(e => e.MissionValueStory)
.WithOne(t => t.Company)
.HasForeignKey(m => m.CompanyId).IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<CompanyInfo>()
.HasMany(e => e.Translation)
.WithOne(t => t.CompanyInfo).IsRequired();
&#13;
答案 0 :(得分:1)
您正在尝试做的事情是合法的不受支持。至少在你做这件事的方式上。幸运的是,这对你来说是一个相当轻松的解决方案。使用每个层次结构表。
将类CompanyInfo
更改为名为CompanyInfoBase
的抽象类,并将其设为抽象类型。在CompanyInfoBase上创建typeId
摘要。
创建两个实现CompanyInfoBase的新类:
public class MilestoneCompanyInfo : CompanyInfoBase
{
public override long typeId { get; set; } = MILESTONE_TYPE_ID;
}
public class MissionValueStoryCompanyInfo : CompanyInfoBase
{
public override long typeId { get; set; } = MISSION_VALUE_STORY_TYPE_ID;
}
其中MILESTONE_TYPE_ID
和MISSION_VALUE_STORY_TYPE_ID
是某种预定义的常量。
然后,在你的DbContext的OnModelCreating中,使用typeId作为你的鉴别器。
它看起来像这样:
modelBuilder.Entity<CompanyInfoBase>()
.HasDiscriminator<long>(nameof(CompanyInfoBase.typeId))
.HasValue<MilestoneCompanyInfo>(MILESTONE_TYPE_ID)
.HasValue<MissionValueStoryCompanyInfo>(MISSION_VALUE_STORY_TYPE_ID);
由于您正在更改实体的名称,因此值得设置表名以适应您现有的数据库。类似的东西:
modelBuilder.Entity<CompanyInfoBase>().ToTable("CompanyInfos");
其他读者注意:由于他决定使用long
,因此只需要定义这样的鉴别器。如果他刚刚离开它未定义,那么EF Core会自动处理这个(通过创建一个名为discriminator的列,其中包含具体的类名)。
这是指向继承参考页面的链接:https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/inheritance