2017-08-11 4 views
0

Wie kann ich dem folgenden Code ein Element zu einer der Eigenschaften einer Entität hinzufügen, ohne dessen ID zu kennen und sie aus der Datenbank abzurufen?Aktualisieren von Entitäten ohne den bekannten Primärschlüssel

public async Task BookInPersonVisitAsync(Guid propertyId, DateTime dateTime, CancellationToken token) 
    { 
     var entity = new OnBoardingProcessEntity{ ExternalId = propertyId }; 

     DbContext.OnBoardingProcesses.Attach(entity); 

     entity.OnBoardingProcessVisits.Add(new OnBoardingProcessVisitEntity 
     { 
      DateTime = dateTime, 
      Occurred = false 
     }); 

     await DbContext.SaveChangesAsync(token); 
    } 

ExternalId ist nur eine Anleitung, die wir für externe Referenz verwenden. Dies funktioniert nicht, weil es nicht die ID gesetzt hat, aber ohne die Datenbank zu treffen, können wir es nicht haben.

Antwort

0

Mit Entity-Framework, wenn Sie eine Entität (referencedEntity) von einer anderen Entität (entity) referenzieren müssen Sie referencedEntity kennen.
Andernfalls können Sie hinzufügen, nur die Entität referencedEntity auf Null setzen.
Um die referenzierteEntity zu kennen, oder Sie kennen die Id oder müssen Sie es in mancher Hinsicht (aus der Datenbank) abrufen.

In SQL (DML), wenn (und nur dann) ExternalId ein Kandidatenschlüssel noy nullable ist, können Sie die OnBoardingProcessVisit Datensatz mit einem einzigen Roundtrip einfügen, aber die Insert-Anweisung wird eine innere Abfrage enthält.

OnBoardingProcessVisit.OnBoardingProcess_Id = (
    SELECT 
     Id 
    FROM 
     OnBoardingProcess 
    WHERE 
     ExternalId = @propertyId) 

EDIT
keine Möglichkeit, dass Abfrage mit EF zu erzeugen. Sie können sich externe Komponenten ansehen (kostenlos und nicht kostenlos, z. B. EntityFramework Extended, aber in diesem Fall ist das nicht hilfreich).

In diesem Fall würde ich wahrscheinlich versuchen, Standard-Entity-Framework-Funktionen zu verwenden (also 1 Roundtrip, um die OnBoardingProcess aus der ExternalId abrufen).
Wenn der Roundtrip zu langsam ist, führen Sie die SQL-Abfrage direkt in der Datenbank aus.
Über Leistungen (und Konsistenz der Datenbank) fügen Sie einen eindeutigen Index auf OnBoardingProcess.ExternalId (in jedem Fall).

Ein weiterer Vorschlag, wenn Sie sich für die Rundreise entscheiden. In Ihrem Code wird entity ein Proxy sein. Wenn Sie den Lazy Load nicht deaktivieren, verwenden Sie Ihren Code, um einen weiteren Rundlauf durchzuführen, wenn Sie auf die Eigenschaft entity.OnBoardingProcessVisits (in der Anweisung entity.OnBoardingProcessVisits.Add) zugreifen.
Also, in diesem Fall deaktivieren Sie Lazy Load oder machen Sie das gleiche auf andere Weise.
Die unterschiedliche Art und Weise in Ihrem Fall ist so etwas wie

var onBoardingProcessVisitEntity new OnBoardingProcessVisitEntity 
{ 
    DateTime = dateTime, 
    Occurred = false, 
    OnBoardingProcess = entity 
}); 

DbContext.OnBoardingProcessVisits.Add(onBoardingProcessVisitEntity); 
await DbContext.SaveChangesAsync(token); 
+0

danken Ihnen für Sie Eingabe, Die Sache ist, wie kann ich das EF machen ein Skript erzeugen wie in Ihrem Beispiel? Ich kann jetzt in EF sagen, dass die externe ID ein Kandidatenschlüssel ist. – Marco

+0

Siehe den Abschnitt Bearbeiten in der Antwort – bubi

+0

Es scheint, ich könnte HasAlternateKey in den neuesten Versionen des EF verwenden :(Danke für Ihre Hilfe. – Marco

Verwandte Themen