DomPazz
DomPazz

Reputation: 12465

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?

Upvotes: 1

Views: 678

Answers (2)

DomPazz
DomPazz

Reputation: 12465

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.

Upvotes: 0

Yuliam Chandra
Yuliam Chandra

Reputation: 14640

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

Upvotes: 1

Related Questions