简体   繁体   中英

Using a written class as a base type for an EF6 entity

I'm new to EF and am still working up the learning curve.

I have 2 tables ScheduledEvent and RealizedEvent. Obviously these are both events with similar properties, but they also have some differing properties. A scheduled event will generate a realized event record, but a realized event does not have to be scheduled. For simplicity, I went with 2 tables in the database.

In C#, I would like to have a base event class that both these entities inherit.

I've tried

public class BaseEvent
{
    public virtual int ID { get; set; }
    ... /*All overlapping properties*/
}

public partial class ScheduledEvent : BaseEvent
{ ... }

This generates warnings because the EF auto-generated classes do not override the methods and properties.

I can see in the .edmx window where I can specify a Base Type for the entities, but it does not allow me to choose a user written class. I guess I could define a table with the overlapping fields, specify that in the Base Type , and never put data in it, but that seems silly.

Is there a better way to do this?

Since you are using database first, you need to refactor your database too to introduce a base class in the database.

Here is an example of schema that has Person , User and Contact table. Person table represents a base class in the entity model.

create table [Person] (
   Id int identity primary key,
   Code nvarchar(max),
   FirstName nvarchar(max),
   LastName nvarchar(max)
   /* other overlapping columns */
)
create table [User] (
   Id int primary key, /* PK but also FK */
   UserName nvarchar(max),
   Password nvarchar(max),   
   foreign key(Id) references [Person](Id) on delete cascade
)
create table [Contact] (
   Id int primary key, /* PK but also FK */
   City nvarchar(max),
   PostalCode nvarchar(max),
   foreign key(Id) references [Person](Id) on delete cascade
)

Then you generate the entity model from database. By default the generated diagram will show you the one to zero-or-one relationship.

Then do the following in the diagram

  • Delete the the one to zero-or-one relationship association
  • Mark Person as Abstract
  • Set User's and Contact's BaseType to Person
  • Delete the Id property from User and Contact
  • Open Table Mapping for User and Contact, then map the Id column to Id property
  • Save

The generated DbContext will only have one DbSet of type Person.

public virtual DbSet<Person> People { get; set; }

More

I created an interface for the base and then had each of the entities implement that interface.

public interface IEvent
{
   ...
}
public partial class ScheduledEvent : IEvent
{
   ...
}
public partial class RealizedEvent : IEvent
{
   ...
}

This then lets me build a collection of Events. I can access all the shared properties and methods of IEvent and check type when needed.

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