Я пытаюсь работать с 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] сопоставляются в обоих фрагментах с различными концептуальными свойствами сторон.
Я не понимаю, почему это разрешено для двух подклассов, но не для третьего.
Может быть, есть лучшее решение для этого (без изменения схемы базы данных)?