Создать отношения с n другими объектами, наследующими от того же класса - PullRequest
0 голосов
/ 21 апреля 2020

У меня есть пять сущностей. Я хочу избежать использования стратегии TPH, встроенной в EF Core, поскольку полученная таблица представляет собой полный беспорядок.

Пять сущностей можно показать так:

public abstract class A {
    public int Id { get; set; }
}

public class B : A {
    public string Foo { get; set; }
}

public class C : A {
    public string Bar { get; set; }
}

public class DA<TType> where TType : A {
    public int DId { get; set; }
    public D D { get; set; }

    public int AId { get; set; }
    public TType A { get; set; }
}

public class D {
    public int Id { get; set; }
}

Что нужно извлечь отсюда: B и C наследуют от A, DA - тип прокси для отношения n: m между D и A (имеется в виду B и C), я пропустил навигационные свойства.

My DbContext выглядит так:

public class ApplicationDbContext : DbContext
{
    public DbSet<D> Ds { get; set; }

    public DbSet<B> Bs { get; set; }
    public DbSet<DA<B>> BDAs { get; set; }

    public DbSet<C> Cs { get; set; }
    public DbSet<DA<C>> CDAs { get; set; }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        // Configure B to D with n:m relation via DA
        builder.Entity<DA<B>>()
            .HasKey(d => new { d.DId, d.AId });
        builder.Entity<DA<B>>()
            .HasOne(d => d.D)
            .WithMany()
            .HasForeignKey(d => d.DId);
        builder.Entity<DA<B>>()
            .HasOne(d => d.A)
            .WithMany()
            .HasForeignKey(d => d.AId);

        // Configure C to D with n:m relation via DA
        builder.Entity<DA<C>>()
            .HasKey(d => new { d.DId, d.AId });
        builder.Entity<DA<C>>()
            .HasOne(d => d.D)
            .WithMany()
            .HasForeignKey(d => d.DId);
        builder.Entity<DA<C>>()
            .HasOne(d => d.A)
            .WithMany()
            .HasForeignKey(d => d.AId);
    }
}

Теперь на мои вопросы:

  1. Теперь весь пример - моя текущая реализация для достижения этой цели. К сожалению, это очень много кода, который нужно добавить для каждой дополнительной сущности. Есть ли какой-то механизм / подход (помимо TPH, который использует одну таблицу), который позволяет мне сделать это:
// Reusing classes A, B, C and D from above

public class DA {
    public int AId { get; set; }
    public A A { get; set; }

    public int DId { get; set; }
    public D D { get; set; }
}

// Then only have one DbSet in the ApplicationDbContext with this:
public DbSet<DA> DAs { get; set; }

Я вижу необходимость в дискриминаторе или подобном для обработки разных таблиц, но не могу придумать никакого подхода, чтобы справиться с этим прямо сейчас. У вас есть идея?

Отдельно: могу ли я применить конфигурацию к A и заставить B и C автоматически наследовать эту конфигурацию? Я мог бы сделать это, используя атрибуты, но хочу избежать ссылки на EF Core в моем доменном проекте. Я имею в виду: есть ли способ справиться с этим с помощью Fluent API?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...