Speichern der von Entity Framework übernommenen Typen nicht möglich

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

Frage

Ich habe in meinem Datenmodell eine Tabelle pro Typ-Vererbung implementiert (im Wesentlichen einen BaseEntity Typ mit allen Basisinformationen für meine Elemente und einen Employer Typ, der vom BaseEntity Element erbt). Alles scheint korrekt eingerichtet zu sein, und wenn Sie die Entitäten verwenden (entweder über ADO.net Data Services oder über Linq zu Entitäten), kann ich den Employer Typ sehen und die Dinge scheinen in Ordnung zu sein. Das Problem beginnt, wenn ich eine neue Employer Entität erstelle und versuche, sie zu speichern.

In dem Kontext, bei dem es sich nicht um ein .AddToEmployer Element handelt (nur und AddObject oder AddToBaseEntity ).

Wenn ich AddObject("Employer", NewEmployer) ich folgende Fehlermeldung:

Der EntitySet-Name 'DataEntities.Employer' wurde nicht gefunden.

Wenn ich AddToBaseEntity(NewEmployer) verwende, AddToBaseEntity(NewEmployer) ich eine Fehlermeldung:

Es kann keine gültige Reihenfolge für abhängige Vorgänge ermittelt werden. Abhängigkeiten können aufgrund von Fremdschlüsseleinschränkungen, Modellanforderungen oder Speichern von generierten Werten bestehen.

Habe ich einen Schritt beim Einrichten der Vererbung verpasst? Gibt es eine bestimmte Möglichkeit, vererbte Objekte zu speichern? Was mache ich falsch? Ich AddToEmployer davon aus, dass das grundlegende Problem darin besteht, dass ich einen AddToEmployer sollte. Was muss ich tun, um dies AddToEmployer ? Es scheint seltsam, dass dies keine Option ist, da ich den Employer-Typ auf der Client-Seite sehen kann und Folgendes ausführen kann:

var NewEmployer = new Employer() - was darauf schließen lässt, dass ich den Typ des Arbeitgebers gut sehen kann.

Akzeptierte Antwort

Ich habe ein paar Dinge geändert und konnte dies zum Laufen bringen. Ich bin mir nicht ganz sicher, was das Basisproblem war, aber ich wollte posten, was ich getan habe.

Tabellen neu erstellen: Ich habe die Tabellen neu aufgebaut, wobei ich nur die ID / Key-Spalten und eine einzelne Datenspalte aufrief.

Zusätzliche Felder für die automatische Inkrementierung wurden entfernt: Ich hatte eine automatische Inkrementierungs-ID für BaseEntity und für den Arbeitgeber. Ich habe die automatisch inkrementierende ID auf dem Arbeitgeber entfernt und hatte die Spalte Employer.BaseEntityID und den Fremdschlüssel wieder in BaseEntity.BaseEntityID. (Dies scheint der Täter gewesen zu sein, aber ich hatte den Eindruck, dass dies erlaubt war.)

Leider führt dies dann zu dem Problem, dass die geerbten Klassen im Entity-Framework keine Navigationseigenschaften haben können (alle Navigationseigenschaften müssen sich auf der Basisentität befinden), sodass die Vererbung für unsere Bedürfnisse nicht verwendbar sein wird.


Beliebte Antwort

Mein Name ist Phani und ich arbeite im ADO.NET Data Services-Team.

Mit den Methoden ResolveName und ResolveType können Sie die ResolveType anpassen, die der Client in die an den Server gesendeten Nutzdaten schreibt und wie die Antwort-Nutzdaten vom Server ResolveType werden.

Sie helfen Ihnen beim Auflösen von Typen auf dem Client und sind in vielen Szenarien hilfreich. Einige Beispiele sind:

  1. Die Typhierarchie der Entitäten unterscheidet sich auf dem Client vom Server.
  2. Vom Service bereitgestellte Entitätstypen nehmen an der Vererbung teil und Sie möchten mit abgeleiteten Typen auf dem Client arbeiten.

ResolveName wird verwendet, um den Namen der Entität zu ändern, die wir bei einer Anfrage an den Server auf den Draht legen.

Betrachten Sie dieses Datenmodell: Auf dem Server

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

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

Wenn Sie den Client verwenden, um mit Instanzen des Manager-Entitätstyps zu arbeiten, erwarten Sie nach Übermittlung der Änderungen an den Server, dass Typinformationen in der Nutzlast vorhanden sind, wenn Entitäten an der Vererbung teilnehmen.

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

Wenn der Client diese Nutzdaten serialisiert, wird jedoch "Employee" als Typname angegeben, der nicht auf dem Server erwartet wird. Daher müssen Sie auf dem Client einen Namensauflöser angeben.

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;
}

Ein Typenauflöser wird auf dieselbe Weise verwendet.

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);
}


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum