Не удается переименовать столбец «Дискриминатор» в базе данных Entity Framework 4.1 Code First - PullRequest
3 голосов
/ 10 июля 2011

У меня есть конфигурация иерархии моделей, например:

[Table("A")]
abstract class A { }

class B : A { } // treated as abstract

[Table("C")]
class C : B { }

Это приводит к TPH для A и B и TPT для C. До сих пор это, кажется, работает нормально. Генерируются две таблицы базы данных: «A», которая содержит записи модели A и B, и «C», которая содержит только столбцы записей модели C, еще не сохраненные в таблице «A».

Для схемы TPH в таблице A существует сгенерированный столбец «Дискриминатор», который EF CF создает самостоятельно, чтобы отличить тип A от типа B. Этот столбец является нормальным и ожидаемым; Тем не менее, я хотел бы переименовать его . Ради этого поста новое имя может быть "Тип".

Похоже, что в руководствах, которые описывают, как это сделать:

modelBuilder.Entity<A>()
   .Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name))
   .Map<C>(m=>m.Requires("Type").HasValue(typeof(C).Name));

Это, похоже, не работает, так как я получаю ошибку времени выполнения во время генерации базы данных, говорящую, что модели типов A, B и C добавляются в одну таблицу, и "условия отображения могут использоваться для различать строки, в которые отображаются эти типы. " (Что бы это ни значило.)

Я тоже пробовал:

modelBuilder.Entity<A>()
    .Map<B>(m=>m.Requires("Type"))
    .Map<C>(m=>m.Requires("Type"));

.. а также ..

modelBuilder.Entity<A>().Map(m=>m.Requires("Type"));

.. и хотя эти попытки компилируются и не приводят к ошибкам во время выполнения, похоже, что никакого эффекта не произойдет, поскольку столбец «Дискриминатор» остается как «Дискриминатор».

Я попытался создать новое строковое свойство в A под названием «Дискриминатор», к которому я собирался впоследствии переименовать метаданные столбца свойства, но в результате я получил два столбца «Дискриминатор»: «Дискриминатор» и «Дискриминатор1».

Идеи

Ответы [ 2 ]

1 голос
/ 11 июля 2011

Не только ответ, но и подтверждение того, что подход должен работать ...

Мне только что удалось переименовать поле дискриминатора в используемую нами структуру TPH. Иерархия имеет значение перечисления для различения типов.
A - базовый класс, B - немного более изощренная версия, C, D и E - конкретные классы.

класс А
класс B: A
класс C: B
класс D: B
класс E: A

modelBuilder.Entity<A>()
            .Map<B>(m => m.Requires("TypeId").HasValue((int)MyType.ClassB))
            .Map<C>(m => m.Requires("TypeId").HasValue((int)MyType.ClassC))
            .Map<D>(m => m.Requires("TypeId").HasValue((int)MyType.ClassD))
            .Map<E>(m => m.Requires("TypeId").HasValue((int)MyType.ClassE));

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

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

Сообщение об ошибке, которое вы упоминаете в комментарии, звучит так, будто некоторые требования HasValue приводят к одному и тому же значению для разных типов классов - возможно.

Edit:
Просто прочитайте этот , который, кажется, имеет дело с тем же сообщением об ошибке.

0 голосов
/ 11 июля 2011

Невозможно отобразить дискриминатор для C, поскольку он не является частью вашей иерархии TPH.Попробуйте только это:

modelBuilder.Entity<A>()
            .Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name));
...