我尝试使用Entity Framework 6.2和一个预先存在的数据库。我不允许更改数据库架构。该数据库带有一个针对所有N对M关系的常规表。
表结构为
KEY_TYPE
:键列的表名KEY_ID
:FK到密钥表VALUE_TYPE
:值列的表名VALUE_ID
:FK到值表数据库不使用FK约束。
我需要将其转换为EF模型以处理实体关系。
我尝试使用继承将不同的关系放在同一列中。我为所有常规列创建了一个基类LinkTable
。然后,我为每个包含关系信息的关系类型创建了子类。然后,将关系添加到ModelBuilder
。
[Table("LinkTable")]
public class LinkTable
{
public string ID {get;set;}
//some general columns
}
public class ABLinkTable : LinkTable
{
[Column("KEY_ID")]
public string KEY_ID { get; set; }
public A AObj { get; set; }
[Column("VALUE_ID")]
public string VALUE_ID { get; set; }
public B BObj { get; set; }
}
public class CDLinkTable : LinkTable
{
[Column("KEY_ID")]
public string KEY_ID { get; set; }
public C CObj { get; set; }
[Column("VALUE_ID")]
public string VALUE_ID { get; set; }
public D DObj { get; set; }
}
public class A
{
public List<ABLinkTable> LinksToB {get;set;}
}
public class B
{
public List<ABLinkTable> LinksToA {get;set;}
}
public class C
{
public List<CDLinkTable> LinksToD {get;set;}
}
public class D
{
public List<CDLinkTable> LinksToC {get;set;}
}
public class MyDbContext : DbContext
{
public virtual DbSet<LinkTable> LinkTable{ get; set; }
public virtual DbSet<A> A {get; set; }
public virtual DbSet<B> B {get; set; }
public virtual DbSet<C> C {get; set; }
public virtual DbSet<D> D {get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<LinkTable>()
.HasKey(v => v.ID)
.Map<ABLinkTable>(m =>
{
m.Requires("KEY_TYPE").HasValue("A");
m.Requires("VALUE_TYPE").HasValue("B");
})
.Map<CDLinkTable>(m =>
{
m.Requires("KEY_TYPE").HasValue("C");
m.Requires("VALUE_TYPE").HasValue("D");
})
modelBuilder.Entity<ABLinkTable>()
.HasOptional(k => k.AObj)
.WithMany(s => s.LinksToB )
.HasForeignKey(k => k.KEY_ID);
modelBuilder.Entity<ABLinkTable>()
.HasOptional(k => k.BObj)
.WithMany(s => s.LinksToA )
.HasForeignKey(k => k.VALUE_ID);
modelBuilder.Entity<CDLinkTable>()
.HasOptional(k => k.CObj)
.WithMany(s => s.LinksToD )
.HasForeignKey(k => k.KEY_ID);
modelBuilder.Entity<CDLinkTable>()
.HasOptional(k => k.DObj)
.WithMany(s => s.LinksToC )
.HasForeignKey(k => k.VALUE_ID);
}
}
对于LinkTable
的两个不同子类来说,它工作正常。但是,如果添加第三个,则在EF初始化期间会出现以下错误:
错误3007:映射片段的问题从第852、860行开始:[KEY_ID]列在两个片段中都被映射到不同的概念性侧面属性。
我不明白为什么它允许两个子类,但不允许第三个子类。 也许有更好的解决方案(无需更改数据库架构)来解决此问题?