Arbeiten mit Entitätsschlüsseln (Entity Framework)

Jeder Entitätstyp verfügt über einen Schlüssel, der auf einer oder mehreren skalaren Eigenschaften der Entität basiert. Schlüssel werden durch das Key-Element im konzeptionellen Modell definiert. Wie in relationalen Datenbanken werden diese Schlüsselwerte verwendet, um die Eindeutigkeit einer angegebenen Entität zu überprüfen und die Leistung von Abfragen zu verbessern. Normalerweise werden Schlüsseleigenschaften einer Schlüsselspalte in der zugrunde liegenden Tabelle zugeordnet, und zwar entweder einer Identitätsspalte oder einer anderen Spalte, die mithilfe einer Einschränkung einen eindeutigen Wert garantiert. Weitere Informationen dazu, wie Schlüssel im konzeptionellen Modell definiert werden, finden Sie unter Key-Element (CSDL).

Wenn ein Objekt von einer Objektabfrage zurückgegeben wird, materialisiert Entity Framework das Entitätsobjekt. Außerdem wird der Entitätsschlüssel in eine Instanz der EntityKey-Klasse überführt. Sie können auf diesen EntityKey über die EntityKey-Eigenschaft eines Objekts zugreifen, das IEntityWithKey implementiert. EntityObject, die Basisklasse aller mit Entity Data Model -Tools generierten Datenklassen, implementiert ebenfalls IEntityWithKey.

Dd283139.note(de-de,VS.100).gifHinweis:
In Entity Framework ist es nicht erforderlich, IEntityWithKey in einer benutzerdefinierten Datenklasse zu implementieren.

Erstellen und Verwenden eines EntityKey-Objekts

Ein EntityKey-Objekt besteht aus den Eigenschaften EntitySetName und EntityContainerName sowie einem Array von einem oder mehreren Schlüssel-Wert-Paaren. Ein Schlüssel-Wert-Paar besteht aus einem Eigenschaftsnamen und einem Eigenschaftswert. Sie geben Schlüssel-Wert-Paare in Form von einem oder mehreren EntityKeyMember-Objekten in der EntityKeyValues-Eigenschaft an.

Dd283139.note(de-de,VS.100).gifHinweis:
Wenn Sie einen der EntityKey-Konstruktoren verwenden, besteht der im qualifiedEntitySetName-Parameter angegebene Zeichenfolgenwert aus dem EntitySetName, dem der EntityContainerName vorangestellt wird, wie in "EntityContainerName.EntitySetName".

Sie können auch die CreateEntityKey-Methode von ObjectContext verwenden, um den EntityKey für ein getrenntes Objekt abzurufen. Wenn das Objekt über keinen gültigen Schlüssel verfügt, erstellt der Objektkontext eine neue EntityKey-Instanz für das angegebene Objekt. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines EntityKey (Entity Framework).

Da ein Entitätsschlüssel eine Entität eindeutig identifiziert, können Sie eine Entität erstellen, die nur den Schlüssel enthält, und das Objekt einem Objektkontext anfügen, auch wenn die verbleibenden Objektwerte nicht aus der Datenquelle abgerufen wurden. Weitere Informationen finden Sie unter Gewusst wie: Anfügen verbundener Objekte (Entity Framework). Ein Entitätsschlüssel kann auch dazu verwendet werden, ein Objekt entweder aus dem Objektkontext oder der Datenquelle abzurufen. Weitere Informationen finden Sie unter Gewusst wie: Zurückgeben eines bestimmten Objekts anhand seines Schlüssels (Entity Framework).

Entitätsschlüssel mit fester Länge

Entity Framework führt die Identitätsauflösung auf Grundlage des EntityKey-Werts durch, der einem Primärschlüssel in der Datenbank entspricht. Wenn eine Abfrage ein Objekt mit einem EntityKey zurückgibt, der bereits im ObjectContext vorhanden ist, wird kein neues Objekt erstellt. Wenn Sie mit Spalten fester Größe in der Datenbank arbeiten und Werte speichern, die kürzer sind als die in der Datenbank angegebenen Größen, füllen einige Datenbanken Typen mit fester Größe mit Leerzeichen oder Nullen auf. SQL Server füllt Zeichenfolgentypen mit fester Größe mit nachgestellten Leerzeichen auf. Wenn Typen mit fester Größe (z. B. "binary" oder "char") als Primärschlüssel verwendet werden, können Identitätsauflösungsprobleme auftreten.

Betrachten Sie das folgende Beispiel. Die Product-Tabelle hat eine Spalte mit fester Länge der Größe 10 für den Primärschlüssel. Es wird ein Product-Objekt mit EntityKey AB100 erstellt und dem ObjectContext hinzugefügt. Bei der Speicherung des Objekts in der Datenbank wird der Schlüssel mit nachgestellten Leerzeichen aufgefüllt, da die Spalte eine feste Größe aufweist und der gespeicherte Wert kürzer ist als die Größe in der Datenbank. Eine nachfolgende Abfrage nach einem Objekt mit einem EntityKey-Wert von AB100 gibt ein Objekt mit einem anderen EntityKey-Wert (AB100 gefolgt von Leerzeichen) zurück, da SQL Server den Wert AB100 als übereinstimmend mit der aufgefüllten Zeichenfolge ansieht. Entity Framework schneidet die Werte von Eigenschaften nicht ab und füllt diese nicht auf. Im Ergebnis wird ein neues Objekt (mit dem EntityKey-Wert AB100 gefolgt von Leerzeichen) dem ObjectContext hinzugefügt.

Product p1= new Product 
{ 
    ProductID = "AB100", 
    Description = "New product" 
}; 
// An object with EntityKey "AB100" is added to ObjectContext.  ctx.Products.AddObject(p1); 
// The object is saved in the database with a primary key of 
// "AB100     " because the column is of a fixed size.  ctx.SaveChanges();
// When a query is executed for an object with key "AB100", SQL Server // matches the key to "AB100     ".  The result is that a new object 
// with EntityKey "AB100     " is added to ObjectContext.  Product p2 = ctx.Products.First(p => p.ProductCode == "AB100");  

Mit einer der folgenden Maßnahmen können Sie dieses unerwünschte Verhalten vermeiden:

  • Verwenden Sie einen Typ mit variabler Länge anstelle eines Typs mit fester Länge in der Datenbank.

  • Füllen Sie den Wert von EntityKey auf dem Client mit nachfolgenden Leerzeichen oder Nullen auf. Sie können eine Zeichenfolge mithilfe der PadRight-Methode mit Leerzeichen auffüllen.

Entitätsschlüssel und hinzugefügte Objekte

Bei der Erstellung einer neuen Entität definiert Entity Framework einen temporären Schlüssel und legt die IsTemporary-Eigenschaft auf true fest. Wenn Sie die SaveChanges-Methode aufrufen, weist Entity Framework einen permanenten Schlüssel zu und legt die IsTemporary-Eigenschaft auf false fest.

Ist der entsprechende Spaltenwert eine Identität, die in der Datenbank generiert wird, dann legen Sie das StoreGeneratedPattern-Attribut des Property-Elements einer Entität im Speichermodell auf Identity fest. Wenn die Entity Data Model -Tools anhand einer vorhandenen Datenquelle ein Datenmodell generieren, wird jedem Property-Element (CSDL)-Element, das eine Identität oder eine berechnete Spalte in der Datenquelle darstellt, das StoreGeneratedPattern-Attribut hinzugefügt. Entity Framework ersetzt den Wert der Eigenschaft in einem temporären Schlüssel durch den Identitätswert, der von der Datenquelle generiert wird, nachdem SaveChanges aufgerufen wurde.

Im Folgenden wird der interne Prozess, der den temporären Schlüssel durch einen permanenten Schlüssel ersetzt, der die Server-generierten Werte enthält, genauer betrachtet:

  1. Das Entitätsobjekt wird erstellt.

    Zu diesem Zeitpunkt sind alle Schlüsseleigenschaften auf Standardwerte festgelegt, entweder NULL oder 0.

  2. Das neue Objekt wird dem ObjectContext hinzugefügt. Dazu wird entweder die AddObject-Methode von ObjectContext oder ObjectSet aufgerufen oder ein Objekt wird zur Auflistung von Objekten am "n"-Ende einer Beziehung hinzugefügt.

    An diesem Punkt generiert Entity Framework einen temporären Schlüssel, der verwendet wird, um die Objekte im ObjectStateManager zu speichern.

  3. SaveChanges von ObjectContext wird aufgerufen.

    Eine INSERT-Anweisung wird von Entity Framework generiert und in der Datenquelle ausgeführt.

  4. Wenn der INSERT-Vorgang erfolgreich war, werden vom Server generierte Werte in den ObjectStateEntry zurückgeschrieben.

  5. Der ObjectStateEntry aktualisiert das Objekt mit dem vom Server generierten Wert.

  6. Mit dem Aufruf von AcceptChanges des ObjectStateEntry wird ein permanenter EntityKey mit den vom Server generierten neuen Werten berechnet.

    Dd283139.note(de-de,VS.100).gifHinweis:
    AcceptChanges wird beim Abschluss der Ausführung von SaveChanges automatisch oder über einen Aufruf der SaveChanges-Methode mit dem AcceptAllChangesAfterSave-Flag aufgerufen.

  7. Der ObjectStateManager ersetzt alle Instanzen des temporären Schlüssels durch den neuen permanenten Schlüssel.

GUID-Eigenschaftswerte

Entity Framework unterstützt Entitätseigenschaften, die einen Guid-Typ zurückgeben, um die Eindeutigkeit sicherzustellen.

Entity Framework unterstützt servergenerierte GUID-Typidentitätswerte. Der Anbieter muss jedoch servergenerierte Identitätswerte nach dem Einfügen einer Zeile zurückgeben können. SQL Server kann ab SQL Server 2005 mithilfe der OUTPUT-Klausel den servergenerierten GUID-Typ zurückgeben. Wenn ein Anbieter keine Entsprechung für die OUTPUT-Klausel unterstützt, generieren Sie im Client GUID-Werte für neue Objekte. Dazu wird empfohlen, das SavingChanges-Ereignis zu behandeln, um im Zustand Added einen neuen GUID-Wert für jedes Entitätsobjekt zu generieren. Weitere Informationen finden Sie unter Gewusst wie: Ausführen von Geschäftslogik beim Speichern von Änderungen (Entity Framework).

Beim Generieren oder Aktualisieren eines Datenmodells mit dem Entity Data Model Wizard oder dem Update Model Wizard werden automatisch GUID-Eigenschaften von Entitätstypen für uniqueidentifier-typisierte Spalten in der Datenquelle generiert. Eine Datenquelle kann auch binäre 16-Byte-Spalten zum Speichern von GUID-Werten verwenden. Da die Tools für jede binäre Spalte in der Datenquelle eine binäre Eigenschaft generieren, müssen Sie die Zuordnung zwischen diesen Spalten und GUID-Eigenschaften durch Bearbeiten der EDMX-Datei manuell aktualisieren. Weitere Informationen finden Sie unter How to: Map a GUID Property to a Binary Column.

In diesem Abschnitt

Gewusst wie: Erstellen eines EntityKey (Entity Framework)

Siehe auch

Aufgaben

Gewusst wie: Erstellen eines EntityKey (Entity Framework)

Weitere Ressourcen

Entity Data Model Tools