Frage

ich eine Tabelle pro Typen implementiert habe Vererbung in meinem Datenmodell (hat grundsätzlich einen BaseEntity Typen mit allen Basisinformationen für meine Artikel und eine Employer Art, die aus dem BaseEntity Elemente erbt). Alles scheint richtig eingerichtet zu werden, und wenn die Einheiten (entweder über ADO.net Data Services oder über Linq to Entities) Ich kann den Employer Typ sehen und Dinge zu sein scheinen in Ordnung. Das Problem beginnt, wenn ich eine neue Employer Einheit schaffen und versuchen, es zu speichern.

Auf dem Kontext, der nicht erscheint ein .AddToEmployer Element zu sein (nur und AddObject oder AddToBaseEntity).

Wenn ich AddObject("Employer", NewEmployer) verwende ich bekommen und Fehlermeldung:

  

Der EntitySet Name 'DataEntities.Employer' konnte nicht gefunden werden.

Wenn ich AddToBaseEntity(NewEmployer) verwende ich erhalte eine Fehlermeldung aus:

  

Es kann keine gültige Reihenfolge für abhängige Operationen bestimmen. Abhängigkeiten können aufgrund von Fremdschlüssel-Constraints existieren, Modellanforderungen orstore Werte erzeugt werden.

Habe ich einen Schritt verpasst in das Erbe der Einrichtung? Gibt es eine bestimmte Art und Weise Objekte zu speichern, die vererbt werden? Was mache ich falsch? Ich gehe davon aus, dass das Grundproblem ist, dass ich eine AddToEmployer haben sollte, was muß ich tun, um das ausgesetzt zu erhalten? Es scheint seltsam, dass es nicht möglich ist, da ich den Arbeitgeber-Typen auf der Client-Seite zu sehen und Dinge tun kann, wie zum Beispiel:

var NewEmployer = new Employer() -. Das scheint darauf hinzudeuten, dass ich den Arbeitgeber mit feinem sehen

War es hilfreich?

Lösung 3

änderte ich ein paar Dinge und war in der Lage, dies zu erhalten, zu arbeiten. Ich bin nicht besonders sicher, was die Basis Problem war, wollte aber schreiben, was ich als Referenz tat.

Rebuilt Tabellen:. Ich baute die Tabellen, beginnend mit nur der ID / Key Spalt und einer einzelnen Datenspalte

Entfernt zusätzliche automatische Inkrementieren Felder: Ich habe eine automatische Erhöhung ID auf dem BaseEntity und auf dem Arbeitgeber. Ich entfernte die automatisch inkrementierende ID auf dem Arbeitgeber und hatte gerade die Employer.BaseEntityID Säule und den Fremdschlüssel zurück zu BaseEntity.BaseEntityID. (Dies scheint der Täter gewesen zu sein, aber ich hatte den Eindruck, dies erlaubt wurde)

Leider führen diese dann auf die Frage, die Klassen im Entity Framework enherited nicht Navigationseigenschaften (alle Navigationseigenschaften müssen auf der Basisentität) haben so Vererbung wird als nicht geeignet für unsere Bedürfnisse zu beweisen.

Andere Tipps

My Name ist Phani und ich arbeite auf dem ADO.NET Data Services-Team.

Die ResolveName und ResolveType Methoden stehen Ihnen die Typinformationen helfen anpassen, dass der Kunde in der Nutzlast auf dem Server und wie die Antwort-Payload vom Server gesendet schreibt materialisiert.

Sie helfen Ihnen Typen auf dem Client zu beheben und sind in vielen Szenarien, ein paar Beispiele hierfür sind:

  1. Die Art Hierarchie von Entitäten ist auf dem Client unterschiedlich im Vergleich zu dem Server.
  2. Entitätstypen durch den Dienst ausgesetzt teilnehmen Erbe und Sie möchten mit abgeleiteten Typen auf dem Client arbeiten.

ResolveName wird verwendet, um den Namen des Unternehmens zu ändern, die wir auf dem Draht setzen, wenn eine Anfrage an den Server zu machen.

Betrachten Sie dieses Datenmodell: On 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, mit Exemplaren des Managers Entitätstyp zu arbeiten, auf die Änderungen an den Server, erwarten wir Informationen sein, die in der Nutzlast geben, wenn Entitäten in Vererbung teilnehmen.

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

Wenn jedoch der Client diese Nutzlast serialisiert, bringt es in „Mitarbeiter“ als Typnamen Das ist nicht das, was auf dem Server erwartet wird. Daher können Sie einen Namen Resolver auf dem Client zur Verfügung stellen müssen,

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 Typ Resolver wird auf die gleiche Art und Weise verwendet wird.

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

Nun, Sie nur eine Einheit Set pr bekommen. Basisklasse ist so .AddToBaseEntity die Lösung als solche.

Aber es klingt wie Sie eine zirkuläre Abhängigkeit in Ihrem Modell haben, so dass der Rahmen Entity nicht, in welcher Reihenfolge herauszufinden, zu speichern.

Überprüfen Sie, ob Sie Fremdschlüssel auf die baseentity auf der abgeleiteten Einheiten und aktualisieren Sie Ihr Modell haben.

Sie haben nicht Arbeitgeber als Einheit Satz definiert, wie Entitätstyp. Das ist so, wie Sie AddToEntity im Kontextobjekt fehlen. Es gibt immer eine Einheit für eine Klassenhierarchie festgelegt, in diesem Fall ist es Baseclass Entitätssatz.

Wenn Sie wollen Entitätssatz ‚Arbeitgeber‘ erhalten, können Sie versuchen, manuell EDMX-Datei zu bearbeiten und neue Einheit Set ‚Arbeitgeber‘ hinzuzufügen, und legen Sie Entitätstyp ‚Arbeitgeber‘ zu dieser Einheit Set gehören. Es sollte nicht schwer sein, ich habe es viele Male getan.

Ich bin nicht sicher, ob es eine regelmäßigere Lösung ist.

über zwei Jahre kommen später, aber im Interesse es relevant für den Suchverkehr zu halten, ist hier eine Weise, die ich in einer Convenience-Klasse um diese schnell gearbeitet, dass wir schnell wurden unter Verwendung unsere Datenbank mit Staging-Daten zu füllen.

über frühere Versionen nicht sicher, aber Entity Framework 4 können Sie das Objekt in den Kontext als Basisobjekt abladen und dann Zahlen der Rahmen für die serverseitige Referenzen aus. So würden Sie nicht verwendet AddToInheritedObjects () (die ohnehin veraltet ist), sondern die ObjectSet <>. In () -Methode.

Hier ist eine Hilfsklasse Beispiel:

public ContextHelper
{
        …
        _context = ModelEntities();

        public T Create<T>() where T : class
        {
            // Create a new context
            _context = new ModelEntities();

            // Create the object using the context (can create outside of context too, FYI)
            T obj = _context.CreateObject<T>();

            // Somewhat kludgy workaround for determining if the object is
            // inherited from the base object or not, and adding it to the context's
            // object list appropriately.    
            if (obj is BaseObject)
            {
                _context.AddObject("BaseObjects", obj);
            }
            else
            {
                ObjectSet<T> set = _context.CreateObjectSet<T>();
                set.AddObject(obj);
            }

            return obj;
        }
        …
}

So vorausgesetzt, Sie haben die folgende:

class ObjectOne : BaseObject {}
class ObjectTwo {}

Sie könnten leicht hinzufügen Einheiten auf den Kontext:

ContextHelper ch = ContextHelper()
ObjectOne inherited = ch.Create<ObjectOne>();
ObjectTwo toplevel = ch.Create<ObjectTwo>();
…

Remembering, natürlich, dass ContextHelper sollte eine öffentliche Methode Save () haben, die _context.SaveChanges () ruft - oder dass Sie eine andere Art und Weise zu schieben das Objekt sollte auf den Datenspeicher ändert sich nach oben

.

Dies könnte nicht eine direkte Antwort auf jede gegebene Frage über die Vererbung, aber hoffentlich gibt die Menschen einen Ausgangspunkt zu beantworten Besonderheiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top