实体框架TPH继承代码第一类

时间:2016-10-31 07:59:08

标签: c# entity-framework inheritance ef-code-first table-per-hierarchy

我不太确定如何正确解决这个问题。

我有一个班级Appointment和一个班级AppointmentSeries,其继承自Appointment

我的数据库首先使用TPH设置代码。

现在,当我获得数据库时,我希望获得Appointment类型的所有行,而不是AppointmentSeries

我尝试使用OfType<Appointment>(),但这也得到AppointmentSeries

我读到我必须使用抽象类来获得正确的行为,但我不想实现抽象类,所以我必须在AppointmentAppointmentSeries中实现相同的属性。或者我必须吗?

我找到的另一个解决方案是为每个查询添加.where(a => !(a is AppointmentSeries))。但这很难看,我得到了整个数据库,然后排除了一些行。

有没有更好的方法只能获得约会或结构我的课程,我可以使用OfType<Appointments>()

一切顺利

Canere

1 个答案:

答案 0 :(得分:0)

我认为您应该尝试抽象类方法。您不必在两个派生类中实现相同的代码。你要做的是定义一个包含当前BaseAppointment类的所有代码的抽象基类Appointment,然后定义Appointment就像一个只扩展基类而没有任何代码的空类(也许只是一个调用基本抽象构造函数的构造函数):

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

AppointmentSeries也扩展了BaseAppointment,没有进一步的更改(除了构造函数调用基础构造函数之外,它可能已经做了)。

DbContext {}为DbSetsAppointment定义AppointmentSeries

通过此操作,您将无法再从AppointmentSeries Appointment获得DbSet

如果您不喜欢这种方法,您还可以考虑从TPH更改为TPT(每种类型的表)或TPC(每个混凝土类的表),并在单独的表中实现这两个实体。

否则我猜你不得不去寻找丑陋且影响性能的.where(a => !(a is AppointmentSeries))或类似的东西。

可行的技巧(但也很难看):如果您的AppointmentSeries具有未在基础Appointment类中定义的非可空属性,则可以将其用作过滤器。此属性在null中始终为Appointments,在not null中始终为AppointmentSeries。您可以在查询中添加过滤器.where(a => !(a.MyProperty is null))。我真的不知道这是否比另一个更好。