问题
I am using the Entity Framework and have an inheritance structure with a base Entity (let's call it Customer) and a derived Entity, let's call it AccountCustomer. The difference is that an AccountCustomer has extra details (such as payment terms etc.) stored in a separate table in the database and therefore extra properties in the Entity.
I want to allow users to 'promote' a specific Customer to be an AccountCustomer. I need to keep the same primary key (a composite key visible to users and used as the customer reference).
At the moment my feeling is that calling a stored procedure to create the additional record in the Accounts table is the only way to go, but up to now we have not bypassed the Entity Framework so would prefer to avoid this technique if possible.
Has anybody any Entity Framework focussed solutions?
回答1:
This is one of those "Please don't do this" scenarios.
You are thinking about this strictly in terms of tables, instead of in object-oriented terms.
A particular customer is a particular customer. The kind of thing he is never changes. Now, his Status may change, or he may acquire additional AccountProperties, but he never transitions from being one kind of thing (Customer) to another kind of thing (AccountCustomer). It simply doesn't make sense conceptually (a generic fruit doesn't morph into an apple, does it? no! it starts as an apple with one status, and ends up as an apple with a new status), and it certainly is impossible in .NET object-oriented programming ... which would make it impossible in an ORM like EF.
So please think about a sensible way to conceptualize this, which will lead to a sensible way to express this in object-oriented terms, which will lead to a sensible EF solution.
回答2:
I have solved this by a work-around.
- Load all the related navigation properties of the base class, including itself
var customer = db.Customers.Include("whatever dependince you have").FirstOrDefault(u=>u.UserId == userId);
//you can repeat this for all of your includes
- Cache the navigation properties to local variables i.e.
var profile = customer.Profile; - Delete the base class by
db.Customer.Remove(customer); - Create the derrived class
var accountCustomer = new AccountCustomer(); - Set all of its properties and navigation properties from the base class i.e.
accountCustomer.UserId = customer.UserId;
accountCustomer.Profile = profile; // do the same for all of the properties and navigation properties from the base class
- Add the new class back to the db
this.Entry<T>(accountCustomer).State = EntityState.Added;
- Call
db.SaveChanges()
That's it!
来源:https://stackoverflow.com/questions/685403/casting-entity-framework-entities-in-the-wrong-direction