简体   繁体   中英

Entity Framework TPH Inheritance Code First oftype

I'm not quite sure how to solve this problem properly.

I have a class Appointment and a class AppointmentSeries with inheritance from Appointment .

My database is set up code-first with TPH.

Now when I get the database, I want to get all rows with the type of Appointment , without the AppointmentSeries .

I tried using OfType<Appointment>() but this also gets the AppointmentSeries .

I read that I have to use abstract classes to get the correct behaviour, but I don't want to implement an abstract class so I have to implement the same properties in Appointment and AppointmentSeries . Or do I have to?

The other solution I found was to add .where(a => !(a is AppointmentSeries)) to every query. But this is ugly and I get the entire database and then exclude some rows.

Is there a better way to get only the Appointments or structure my classes to I can use OfType<Appointments>() ?

All the best

Canere

I think you should give a try to the abstract class approach. You don't have to implement the same code in both derived classes. What you do is defining an abstract base class BaseAppointment containing all the code of your current Appointment class, and then defining Appointment like an empty class that just extends the base class without any code inside (perhaps just a constructor that calls the base abstract constructor):

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

AppointmentSeries also extends BaseAppointment , with no further changes (apart from the constructor calling base constructor as well, which it probably already does).

In your DbContext you define DbSets for Appointment and AppointmentSeries .

With this you will no longer get AppointmentSeries from the Appointment DbSet .

If you don't like this approach you could also consider changing from TPH to TPT (Table Per Type) or TPC (Table Per Concrete Class), and implementing both entities in separate tables.

Otherwise I guess you would have to go for the ugly and performance-impacting .where(a => !(a is AppointmentSeries)) or something similar.

A trick that could work (but it is also ugly): if your AppointmentSeries has a non-nullable property which is not defined in the base Appointment class you can use it as a filter. This property will be always null in Appointments , but not null in AppointmentSeries . You can add a filter .where(a => !(a.MyProperty is null)) to your queries. I don't really know if this has a better performance that the other one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM