EF Core Указание ключа foriegn для справочной таблицы, которая имеет значения из перечисления - PullRequest
0 голосов
/ 16 сентября 2018

Допустим, у меня есть следующая сущность.

public class TestData
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
    public TestType Type { get; set; }
}

Тип теста - это перечисление, но я хотел бы иметь справочную таблицу в базе данных со значениями перечисления. Для этого я создаю сущность TestTypeEntry, которая создается ядром EF, и загружаю ее из значений в перечислении TestType.

public class TestTypeEntry
{
    public int TestTypeEntryID { get; set; }
    public String TestTypeName { get; set; }
}

Теперь я просто хочу создать ограничение внешнего ключа между TestData.Type (перечисление) и TestTypeID таблицы ввода типа теста, используя свободный API.

Эта проблема, по-видимому, является результатом использования перечислений в качестве значений для сущности и желания иметь справочную таблицу в базе данных, которая отражает эти значения с отношением внешнего ключа к ней. Если я не поступлю неправильно, все, чего мне не хватает, - это создать ограничение внешнего ключа для справочной таблицы, используя свободный API. Что-то вроде

Entity<TestData>(td => td.Type).HasForeignKey<TestTypeEntity>(tt => tt.TestTypeEntryID)

Я знаю, что приведенный выше код не работает (просто пытаюсь дать представление о том, что я ищу).

1 Ответ

0 голосов
/ 18 сентября 2018

Используйте преобразование значения EnumToNumberConverter .

Что-то вроде:

var converter = new EnumToStringConverter<TestType>();

modelBuilder
    .Entity<TestData>()
    .Property( td => td.Type )
    .HasConversion( converter );

Редактировать:

После комментариев японимать, что проблема в том, что у вас есть таблица для перечисления в DbContext, но вы просто хотите использовать Enum для присвоения значений.Во-первых, как описано в комментариях, мне не нравится это решение, поскольку оно требует обслуживания данных в двух местах - таблица БД и код Enum.

Однако вы можете выполнить то, что хотите, используя только свойство внешнего ключа без свойства навигации, пометив сеттер как private, а затем используя игнорируемое EF свойство типа Enum для обработки преобразования.к Enum:

public class TestData
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Position { get; set; }
    // FK, private setter
    public int TestTypeEntryId { get; private set; }
    // enum property that EF will ignore
    public TestType Type
    {
        get => ( TestType )TestTypeEntryId;
        set => TestTypeEntryId = ( int )value;
    }
}

Конфигурация модели для TestData

        builder.HasOne<TestTypeEntry>()
            .WithMany()
            .HasForeignKey( d => d.TestTypeEntryId );

        builder.Ignore( d => d.Type );

Обратите внимание, что использование Enum не препятствует установке недопустимых значений.

...