Используйте один и тот же столбец с инерцией в разных фрагментах для разных концептуальных сторон - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь работать с Entity Framework 6.2 и существующей базой данных. Мне не разрешено изменять схему базы данных. База данных поставляется с общей таблицей для всех отношений N к M.

Структура таблицы

  1. KEY_TYPE: имя таблицы ключевого столбца
  2. KEY_ID: FK для таблицы ключей
  3. VALUE_TYPE: имя таблицы столбца значений
  4. 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] сопоставляются в обоих фрагментах с различными концептуальными свойствами сторон.

Я не понимаю, почему это разрешено для двух подклассов, но не для третьего. Может быть, есть лучшее решение для этого (без изменения схемы базы данных)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...