Код наследования TPH Entity Framework Первый тип

Я не совсем уверен, как правильно решить эту проблему.

У меня есть класс Appointment и класс AppointmentSeries с наследованием от Appointment.

Моя база данных настроена с использованием кода сначала с помощью TPH.

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

Я пробовал использовать OfType<Appointment>(), но он также получил AppointmentSeries.

Я читал, что мне нужно использовать абстрактные классы, чтобы добиться правильного поведения, но я не хочу реализовывать абстрактный класс, поэтому мне нужно реализовать те же свойства в Appointment и AppointmentSeries. Или мне нужно?

Другое решение, которое я нашел, заключалось в добавлении .where(a => !(a is AppointmentSeries)) к каждому запросу. Но это уродливо, и я получаю всю базу данных, а затем исключаю некоторые строки.

Есть ли лучший способ получить только встречи или структурировать мои классы, чтобы я мог использовать OfType<Appointments>()?

Всего наилучшего

Канере


person CanereCurrere    schedule 31.10.2016    source источник
comment
хотите получить все ... Назначение без AppointmentSeries означает, что они не были хорошими кандидатами на наследование с самого начала. В настоящее время ваша серия встреч является встречей.   -  person Henk Holterman    schedule 31.10.2016


Ответы (1)


Я думаю, вам стоит попробовать подход абстрактного класса. Вам не нужно реализовывать один и тот же код в обоих производных классах. Что вы делаете, так это определяете абстрактный базовый класс BaseAppointment, содержащий весь код вашего текущего Appointment класса, а затем определяете Appointment как пустой класс, который просто расширяет базовый класс без какого-либо кода внутри (возможно, просто конструктор, который вызывает базовый абстрактный конструктор) :

class Appointment : BaseAppointment 
{
    public Appointment(...some params) : base(...some params) {}
}

AppointmentSeries также расширяет BaseAppointment без каких-либо дальнейших изменений (кроме конструктора, вызывающего также базовый конструктор, который, вероятно, уже выполняется).

В вашем DbContext вы определяете DbSets для Appointment и AppointmentSeries.

С этим вы больше не получите AppointmentSeries от Appointment DbSet.

Если вам не нравится этот подход, вы также можете рассмотреть возможность перехода с TPH на TPT (таблица на тип) или TPC (таблица на конкретный класс) и реализацию обеих сущностей в отдельных таблицах.

В противном случае, я думаю, вам придется пойти на уродливые и снижающие производительность .where(a => !(a is AppointmentSeries)) или что-то подобное.

Уловка, которая может сработать (но она также уродлива): если ваш AppointmentSeries имеет свойство, не допускающее значения NULL, которое не определено в базовом классе Appointment, вы можете использовать его в качестве фильтра. Это свойство всегда будет null в Appointments, но not null в AppointmentSeries. Вы можете добавить фильтр .where(a => !(a.MyProperty is null)) к своим запросам. Я действительно не знаю, лучше ли у него производительность, чем у другого.

person Diana    schedule 03.11.2016