Могу ли я получить доступ к значению дискриминатора при сопоставлении TPH с помощью Entity Framework 4 CTP5

Использование Entity Framework 4 CTP5 Code First и этот пример

Можно ли получить доступ к значению дискриминатора?

Я хотел бы использовать его в проекции, например

context.BillingDetails.Select(x => new { Number = x.Number, DiscrimitatorValue = /* how do I get the discriminator value? */ });

От этот пост Я понимаю, что дискриминатор не может быть сопоставлен с свойством, но есть ли другой способ его доступа?

Ответ 1

После получения дополнительной информации от Мортеза Манави в комментариях своего сообщения простой ответ - нет

вам следует знать, что столбец дискриминатора используется внутренне с помощью кода First, и вы не можете читать/записывать его значения из точки сопоставления наследования.

Чтобы получить доступ к дискриминатору, мне пришлось бы выполнить SqlQuery по базе данных или изменить мою стратегию сопоставления.

Ответ 2

Я могу опоздать к игре на этом, но я просто добавил свойство getter в базовый класс, который возвратил имя текущего типа:

public string DiscriminatorValue {
    get {
        return this.GetType().Name;
    }
}

Поскольку по умолчанию EF будет использовать это же значение для поля Discriminator, они будут совпадать.

Ответ 3

В остальном я недавно столкнулся с одной и той же проблемой, но считаю, что это все еще актуально для v4 EF Framework.

Сначала создайте представление, которое выбирает значение дискриминатора на два столбца.

create view dbo.vw_BillingDetail
as
    select BillingDetailId, DiscriminatorValue, DiscriminatorValue as DiscriminatorValue2 from dbo.BillingDetail
go

Во-вторых, сопоставьте представление с вашим объектом во время создания контекста:

modelBuilder
    .Entity<BillingDetail>()
    .HasKey(n => n.BillingDetailId)
    .Map(map =>
    {
        map.ToTable("vw_Person");
    })

В-третьих, определите сопоставление дискриминатора для вашего производного класса, используя один из столбцов в вашем представлении:

.Map<MyDerivedBillingDetail>(map =>
{
    map.Requires("DiscriminatorValue2").HasValue("YourValue");
})

Наконец, определите getter и private setter для другого столбца дискриминатора в вашем представлении с помощью аннотации DatabaseGenerated как Computed, чтобы предотвратить обновление/вставку EF для этого поля:

class BillingDetail
{
    public BillingDetailId { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DiscriminatorValue { get; private set; }
}

Вы можете изменить приватный сеттер, который будет защищен, и установить это значение явно во время построения ваших производных объектов, чтобы дискриминатор имел значение до его сохранения:

class MyDerivedBillingDetail : BillingDetail
{
    public MyDerivedBillingDetail()
    {
        this.DiscriminatorValue = "MyValue";
    }
}

Ответ 4

Почему бы вам не использовать следующий запрос?

 var q = con.BillingDetails.OfType<BankAccount>().ToList();