Могу ли я указать столбец дискриминатора с отображением таблицы на тип? - PullRequest
17 голосов
/ 22 августа 2011

У меня есть иерархия классов, которую я хочу отобразить на несколько таблиц, используя Entity Framework 4.1 Code First. Это как таблица для каждого типа (TPT), но я также хочу столбец дискриминатора.

Иерархия выглядит примерно так:

public class Event
{
    public Guid Id { get; set; }
    public string Code { get; set; } // discriminator
    public DateTime Date { get; set; }
}

public class Party : Event
{
    public int AttendeeCount { get; set; }
}

public class BirthdayParty : Party
{
    public int Age { get; set; }
}

public class WeddingParty : Party
{
    public string Surname { get; set; }
}

Это довольно слабый пример, но я надеюсь, что он имеет смысл. Там будет таблица «События», таблица «Вечеринки» и таблица для каждого вида вечеринок. Однако столбец дискриминатора («Код») будет иметь известное значение для каждого типа событий, например, «РОЖДЕНИЕ» для вечеринок по случаю дня рождения или «СВАДЬБА» для вечеринок.

Идея состоит в том, что если я запрашиваю только вечеринки по случаю дня рождения на определенную дату, EF будет знать, что добавит Code = 'BIRTH' к моему запросу, вместо того, чтобы делать связки UNION и JOIN, чтобы определить, какие строки ему нужны.

Я отображаю свои классы самого низкого уровня следующим образом:

var bd = modelBuilder.Entity<BirthdayParty>();
bd.ToTable("BirthdayParties");
bd.Property(p => p.Age).HasColumnName("BirthdayAge");

Теперь мне нужно как-то указать значение дискриминатора. Я пробовал это:

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg =>
    {
        cfg.Requires("Code").HasValue("BIRTH");
    });

... но это жалуется на то, что я не указал имя таблицы внутри вызова Map. Поэтому я попытался перевести туда звонок ToTable:

var bd = modelBuilder.Entity<BirthdayParty>();
bd.Property(p => p.Age).HasColumnName("BirthdayAge");

modelBuilder.Entity<Event>().Map<BirthdayParty>(cfg =>
    {
        cfg.Requires("Code").HasValue("BIRTH");
        cfg.ToTable("BirthdayParties");
    });

... и теперь он думает, что я хочу столбец «Код» в таблице «BirthdayParties», что не правильно. Я уже говорил, что столбец «Код» находится в таблице «События».

Это вообще возможно? Могу ли я объединить использование столбца дискриминатора с отображением таблицы на тип?

Ответы [ 2 ]

8 голосов
/ 22 августа 2011

К сожалению, это не поддерживается.Дискриминатор столбец можно использовать только в TPH.TPT отличается типами сущностей сопоставленными таблицами, и он всегда производит эти ужасные запросы.Это может быть хорошей функцией, поэтому, возможно, предложение по Data UserVoice сделает его одним днем.

Обновление

Уже есть предложение для пользователяозвучить этот заголовок " Поддержка столбцов-дискриминаторов в наследовании TPT ".

0 голосов
/ 01 июня 2017

Я сделал переопределение в SaveChanges, чтобы выполнить нечто подобное. Я просто добавил атрибут в абстрактный класс с именем Descriminator и устанавливал его на основе имени конкретного класса каждый раз, когда добавлялось что-то новое.

public class MyContext : DbContext
{        
    public override int SaveChanges()
    {
        foreach (var item in ChangeTracker.Entries().Where(x=>x.Entity is MyAbstractClass && x.State == EntityState.Added))
        {
            ((MyAbstractClass)item.Entity).Descriminator = item.Entity.GetType().Name;
        }
        return base.SaveChanges();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...