【问题标题】:Entity Framework TPH Inheritance Code First oftype实体框架 TPH 继承代码 First oftype
【发布时间】:2016-10-31 07:59:07
【问题描述】:

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

我有一个类Appointment 和一个类AppointmentSeries 继承自Appointment

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

现在,当我获取数据库时,我想获取类型为 Appointment 的所有行,而不是 AppointmentSeries

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

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

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

有没有更好的方法来只获取约会或构建我的课程,以便我可以使用OfType<Appointments>()

一切顺利

甘蔗

【问题讨论】:

  • “想要得到所有……约会,没有 AppointmentSeries”意味着他们一开始就不是继承的好人选。目前,您的 AppointmentSeries 是一个约会。

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


【解决方案1】:

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

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

AppointmentSeries 还扩展了BaseAppointment,没有进一步的变化(除了构造函数调用基本构造函数,它可能已经这样做了)。

在您的DbContext 中,您为AppointmentAppointmentSeries 定义DbSets

有了这个你将不再从AppointmentDbSet获得AppointmentSeries

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多