Entity Framework could not be saved. Inherited characteristics

.net entity-framework inheritance savechanges table-per-type


In my data model, I've done some table-per-type inheritance (essentially having aBaseEntity type with all of the essential details for my goods and aEmployer a kind that derives fromBaseEntity item). Everything seems to be set up OK, and I can see the results when utilizing the Entities (either via ADO.net Data Services or using Linq to Entities).Employer kind, and everything seems to be in order. When I make a new one, the problem arises.Employer and make an effort to rescue the thing.

According to the context, there doesn't seem to be an.AddToEmployer (Only and) ItemAddObject or AddToBaseEntity ).

If I useAddObject("Employer", NewEmployer) I have the following error:

The EntitySet name 'DataEntities.Employer' could not be found.

If I useAddToBaseEntity(NewEmployer) An error message seems to be:

Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements orstore generated values.

Have I put up the inheritance in the wrong way? Is there a particular technique to preserve inherited objects? Why am I misusing this? I believe the fundamental problem is that I should have anAddToEmployer What must I do to bring it to light? It seems strange that there isn't a choice given that I can see the Employer type on the client side and do actions like:

var NewEmployer = new Employer() - this would appear to indicate that I can clearly identify the Employer type.

3/28/2017 2:16:49 PM

Accepted Answer

After making a few adjustments, I was able to make this work. I wanted to write what I did for reference even though I'm not really sure what the root of the problem was.

Rebuilt Tables: I started again with only the ID/Key columns and one data column in each table.

Removed superfluous auto-incrementing fields: The BaseEntity and the Employer both have auto-incrementing IDs. I only had the Employer after removing the auto-incrementing ID from the Employer. BaseEntityID column and the backward-pointing foreign key. BaseEntityID. (This seems to be the offending behavior, although I thought this was allowed.)

Sadly, this caused another problem: inherited classes in the entity framework cannot have navigation properties; all navigation attributes must be on the base entity. As a result, inheritance is no longer useful for our purposes.

10/24/2008 4:27:36 AM

Popular Answer

Phani here; I'm a member of the ADO.NET Data Services team.

The ResolveName and ResolveType You may use methods to alter the information that the client includes in the payload that is provided to the server and how the payload for the server's response is materialized.

They are helpful in various situations and assist you in resolving client-side types. A few instances include:

  1. In contrast to the server, the type hierarchy of entities is different on the client.
  2. You wish to interact with derived types on the client and inheritance is supported by entity types supplied by the service.

ResolveName while sending a request to the server, is used to modify the name of the object that is sent on the wire.

Take a look at this data model: Using server

public class Employee {
    public int EmployeeID {get;set;}
    public string EmployeeName {get;set;}

public class Manager:Employee {
    public List<int> employeesWhoReportToMe {get;set;}

We anticipate type information to be available in the payload when entities engage in inheritance when you use the client to deal with instances of the Manager Entity Type.

context.AddObject("Employees",ManagerInstance ); <-- add manager instance to the employees set.

However, "Employee" is entered as the type name when the client serializes this payload. This deviates from the server's expectations. Consequently, you must install a name resolver on the client,

context.ResolveName = delegate(Type entityType){
    //do what you have to do to resolve the type to the right type of the entity on the server
    return entityType.FullName;

The same procedure is applied with a Type resolver.

context.ResolveType = delegate(string entitySetName){
    //do what you have to do to convert the entitysetName to a type that the client understands
    return Type.GetType(entitySetName);

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow