Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the auto-generated "Discriminator" column in EntityFramework?

I am working on some code that makes use of single table inheritance via EF4.3.

There is an entity called User and another entity called Admin. Admin inherits from user.

User class

public class User
{
    public int Id {get;set;}
    public string Username {get;set;}
}

Admin class

public class Admin : User { }

EF generated the database tables with a Discriminator column. When an Admin record is added then Discriminator="Admin" and a User record would have Discriminator="User".

My question is, how do I update the Discriminator column if I want to make a User into and Admin?

I tried casting from one object type to the other and saving using EF. but that doesn't change the Discriminator column. How do I change it?

Thanks for any help.

like image 936
quakkels Avatar asked May 23 '12 21:05

quakkels


People also ask

What is discriminator column in Entity Framework?

The Entity Framework Core Fluent API HasDiscriminator method is used to configure aspects of the discriminator column in a table that represents an inheritance hierarchy. By convention, a discriminator column will be configured to use a string data type will be named "Discriminator".

What is discriminator column in database?

The discriminator column itself is used to distinguish between different classes when class hierarchies are mapped flat or vertical. The idea behind the flat and vertical mapping is that every class is mapped into a single row in the base class table. The discriminator value is used to define the type of each row.

Which method is used to apply configuration to entities or their properties in the Entity Framework Core?

Configuration is applied to entities or their properties via chained methods, which is the identifiying feature of the Fluent API pattern.


1 Answers

Objects can't change their types, ever. If you intend to change the "administrator" setting for a user (reasonable), you should do that with an attribute/property, not a type name.

For example, you could have an association between a User object and an Administrator object, rather than wanting to replace the User object with an Administrator subtype.

I wrote about this idea in an old blog post:

One of the mental barriers that you have to get over when designing a good object relational mapping is the tendency to think primarily in object oriented terms, or relational terms, whichever suits your personality. A good object relational mapping, though, incorporates both a good object model and a good relational model. For example, let’s say you have a database with a table for People, and related tables for Employees and Customers. A single person might have a record in all three tables. Now, from a strictly relational point of view, you could construct a database VIEW for employees and another one for customers, both of which incorporate information from the People table. When using a one VIEW or the other, you can temporarily think of an individual person as "just" an Employee or "just" a Customer, even though you know that they are both. So someone coming from this worldview might be tempted to do an OO mapping where Employee and Customer are both (direct) subclasses of Person. But this doesn’t work with the data we have; since a single person has both employee and customer records (and since no Person instance can be of the concrete subtype Employee and Customer simultaneously), the OO relationship between Person and Employee needs to be composition rather than inheritance, and similarly for Person and Customer.

To answer your question directly, there's no way to change this column using EF. You could of course, do it in straight SQL. But for the reason given above, I'd encourage you to change this design.

like image 59
Craig Stuntz Avatar answered Oct 04 '22 13:10

Craig Stuntz