2

I have a small application that uses EF to persist my data.

At the moment I have a single 'Ticket' class that maps directly to a 'Ticket' table.

However, there is now a need to create different types of Ticket (e.g. Cruise Ticket, Airline Ticket, Train Ticket) so I'd like to refactor my code to have these 3 ticket types all inherit from a base ticket class.

Is it possible to perform this kind of refactoring whilst maintaining/modifying the existing database?

My gut feeling is that it would be almost impossible to do this without starting again from scratch by recreating my database, and then copying the data over from the existing database.

3
  • I'm aware of code first migrations and have used it when adding new properties to my classes. I was wondering whether this kind of major re-factoring could still be supported by code first migrations Commented May 6, 2014 at 11:27
  • 1
    i've used code first migrations just fine with new classes and new dbsets. Have you tried that and if so, did you get any issues? Commented May 6, 2014 at 12:20
  • 1
    The first question is whether you should use subclasses at all. Inheritance can be a huge overkill, esp. in combination with an ORM. Often, just adding a Type field can suffice. In the code you can program differences in behavior by other patterns than inheritance. Commented May 6, 2014 at 13:54

2 Answers 2

1

You have to use TableAttribute. For this case EF will create two tables related one to one

[Table("Ticket")]
class Ticket
{
   [Key]
   long ID{get;set;}
}

[Table("AirTicket")]
class AirTicket : Ticket
{
   string SomeSpecialAirProperty{get;set;}
}

Here table Ticket will be a general list of all tikets.

Ticket ticket = db.Ticket.Where(n=>n.ID==ticketID).FirstOrDefault(); 
//the value of ticket will be an object of child (Air or etc Ticket) type 
Sign up to request clarification or add additional context in comments.

4 Comments

Not true, the table attribute is used to implement inheritance in table-per-type. EF has 3 strategies for implementing inheritance weblogs.asp.net/manavi/archive/2010/12/24/…
Yes sure. You may choose the strategy by selection of table name (different or same). But i prefer TablePerType strategy.
You don't have to select the table name. EF uses TPH by default. TPH wins on performance and simplicity and schema evolution is straightforward. You may prefer TPT because the schema is normalised but the OP is not asking for a strategy here, just whether it is possible
Having read through the blogs I've gone with your suggestion and a TPT strategy as I prefer the idea of having a table for each ticket type.
0

Yes it possible to perform this kind of refactoring whilst maintaining/modifying the existing database.

If you add a migration in the normal way then entity framework will add a "Discriminator" column to your Ticket table. You may need to populate existing data with the correct value but it is nullable by default so the database update should not fail.

You can add DbSets to the context for CruiseTicket, AirlineTicket and TrainTicket and these will return only entities of that type. Or you can use your Tickets DbSet to retrieve the tickets like this:

context.Tickets.OfType<CruiseTicket>().FirstOrDefault(n => n.Id == id)

This is the default Table Per Hierarchy Strategy for implementing inheritance. You may prefer Table Per Type or even Table Per Concrete Type

References:

https://stackoverflow.com/a/23426802/150342

https://stackoverflow.com/a/23423820/150342

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.