Entity Framework TPH, изменяющий столбец дискриминатора в абстрактном базовом классе и сценарий с пустым унаследованным классом

У меня есть стол:

Groups
 - Id
 - Name
 - Type

И эта таблица представляет собой группу продуктов, клиентов или поставщиков. Чтобы сгруппировать продукты, мне нужно использовать "P" в столбце "Тип", чтобы сгруппировать клиентов и поставщиков, мне нужно использовать "C" и "S" соответственно.

Интересно, смогу ли я использовать ТПХ здесь. Подобно созданию абстрактного класса Group со всеми полями, кроме Type, затем созданию пустых подклассов ProductGroup, ClientGroup и SupplierGroup, а затем настройке столбца Type в качестве дискриминатора со значениями "P", "C" и "S" для сопоставления их соответствующим классы.

Я пытаюсь сделать это, но кажется, что EF не угадывает мое намерение правильно, когда класс Group является абстрактным или когда унаследованные классы пусты.

Мои занятия похожи на следующие:

abstract class Group {
    public int Id { get; set; }
    public string Name { get; set; }
}

class ProductGroup : Group
{}

// I did not create the other two classes yet.

Моя конфигурация в DbContext выглядит следующим образом:

public class DataContext : DbContext
{
    public DbSet<ProductGroup> ProductGroups { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new GroupConfiguration());
    }
}

class GroupConfiguration : EntityTypeConfiguration<Group>
{
    public GroupConfiguration()
    {
        Map<ProductGroup>(m =>
        {
            m.Requires("Type").HasValue("P");
        });
    }
}

Я думаю, что это должно работать, но используя приведенный выше код, datacontext.ProductGroups вернет все группы, а не только группы продуктов.

Я проверил и обнаружил, что если мой класс группы конкретен, код будет работать, как я ожидаю, группы в datacontext.ProductGroups будут только группами продуктов.

Я также проверил и обнаружил, что если я сохраню свой класс Group абстрактным, но переместу поле "Имя" для класса ProductGroup, код также будет работать так, как я ожидаю.

Интересно, это ошибка или я не на том пути.

Я пришел к этой идее, потому что мой начальник хочет иметь конечную точку "/productgroups" в нашем веб-интерфейсе, и я обнаружил, что было бы интересно иметь определенный класс группы продуктов, который будет использоваться в системе, вместо использования универсальной группы и должен фильтровать .Where(e => e.Type == "P") везде. Я думаю, что последний подход менее понятен при работе с объектами, передаваемыми вокруг.

Кто-нибудь знает, как это решить? Нужно ли мне превращать бетон в класс моей группы? Мне бы не понравилось, что класс Group, кажется, нужен, чтобы быть абстрактным, так как на практике у меня есть только группы с заполненным полем Type.

3 ответа

Чего вам не хватает, так это того, что наследование EF основано на одном полиморфном DbSetв то время как различные стратегии (TPH, TPT и TPC) управляют физической моделью хранения в базе данных.

С этим, как говорится, вам нужно следующее в вашем DbContext (удалить ProductGroups что ты так далеко положил)

public DbSet<Group> Groups { get; set; }

Все операции CRUD должны пройти через это DbSet, Если вам нужны конкретные потомки, вы должны использовать OfType метод. Обратите внимание, что это может создать больше проблем, чем использование одного класса с явным Type свойство, так как EF не предоставляет вам никакого доступа к столбцу дискриминатора, поэтому тщательно подумайте, прежде чем использовать его только для этой цели.

Не уверен, что это проблема, но я помещаю свои сопоставления в метод OnModelCreating объекта DbContext:

// Define DisplayLocation subclasses using discriminator column

modelBuilder.Entity<AbstractDisplayLocation>()
            .Map<VirtualDisplayLocation>(m => m.Requires("Virtual").HasValue(true))
            .Map<PdbLocation>(m => m.Requires("Virtual").HasValue(false));

Я обнаружил проблему.

Я использовал тип Group где-то еще в коде. Когда я удалил все ссылки на тип группы, это сработало!

Спасибо за все ответы, хотя

Другие вопросы по тегам