Ich habe verschiedene Methoden zum Bearbeiten / Aktualisieren eines Datensatzes in Entity Framework 5 in einer ASP.NET MVC3-Umgebung untersucht, aber bisher hat keine davon alle von mir benötigten Kästchen angekreuzt. Ich werde erklären warum.
Ich habe drei Methoden gefunden, bei denen ich die Vor- und Nachteile erwähnen werde:
Methode 1 - Originaldatensatz laden, jede Eigenschaft aktualisieren
var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
original.BusinessEntityId = updatedUser.BusinessEntityId;
original.Email = updatedUser.Email;
original.EmployeeId = updatedUser.EmployeeId;
original.Forename = updatedUser.Forename;
original.Surname = updatedUser.Surname;
original.Telephone = updatedUser.Telephone;
original.Title = updatedUser.Title;
original.Fax = updatedUser.Fax;
original.ASPNetUserId = updatedUser.ASPNetUserId;
db.SaveChanges();
}
Vorteile
- Kann angeben, welche Eigenschaften sich ändern
- Ansichten müssen nicht jede Eigenschaft enthalten
Nachteile
- 2 x Abfragen in der Datenbank, um das Original zu laden und dann zu aktualisieren
Methode 2 - Originaldatensatz laden, geänderte Werte einstellen
var original = db.Users.Find(updatedUser.UserId);
if (original != null)
{
db.Entry(original).CurrentValues.SetValues(updatedUser);
db.SaveChanges();
}
Vorteile
- Es werden nur geänderte Eigenschaften an die Datenbank gesendet
Nachteile
- Ansichten müssen jede Eigenschaft enthalten
- 2 x Abfragen in der Datenbank, um das Original zu laden und dann zu aktualisieren
Methode 3 - Aktuellen Datensatz anhängen und Status auf EntityState.Modified setzen
db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();
Vorteile
- 1 x Abfrage der zu aktualisierenden Datenbank
Nachteile
- Es kann nicht angegeben werden, welche Eigenschaften sich ändern
- Ansichten müssen jede Eigenschaft enthalten
Frage
Meine Frage an euch; Gibt es einen sauberen Weg, wie ich diese Ziele erreichen kann?
- Kann angeben, welche Eigenschaften sich ändern
- Ansichten müssen nicht jede Eigenschaft enthalten (z. B. Passwort!)
- 1 x Abfrage der zu aktualisierenden Datenbank
Ich verstehe, dass dies nur eine Kleinigkeit ist, aber ich vermisse möglicherweise eine einfache Lösung dafür. Wenn nicht Methode wird man sich durchsetzen ;-)
quelle
Antworten:
Du suchst nach:
quelle
Ich mag die akzeptierte Antwort wirklich. Ich glaube, es gibt noch einen anderen Weg, dies zu erreichen. Angenommen, Sie haben eine sehr kurze Liste von Eigenschaften, die Sie niemals in eine Ansicht aufnehmen möchten. Wenn Sie also die Entität aktualisieren, werden diese weggelassen. Angenommen, diese beiden Felder sind Kennwort und SSN.
In diesem Beispiel können Sie Ihre Geschäftslogik im Wesentlichen in Ruhe lassen, nachdem Sie Ihrer Benutzertabelle und Ihrer Ansicht ein neues Feld hinzugefügt haben.
quelle
quelle
Ich habe meiner Repository-Basisklasse eine zusätzliche Aktualisierungsmethode hinzugefügt, die der von Scaffolding generierten Aktualisierungsmethode ähnelt. Anstatt das gesamte Objekt auf "geändert" zu setzen, werden einzelne Eigenschaften festgelegt. (T ist ein generischer Klassenparameter.)
Und dann zum Beispiel anrufen:
Ich mag eine Reise in die Datenbank. Es ist jedoch wahrscheinlich besser, dies mit Ansichtsmodellen zu tun, um zu vermeiden, dass sich Sätze von Eigenschaften wiederholen. Ich habe das noch nicht getan, weil ich nicht weiß, wie ich vermeiden kann, die Validierungsnachrichten auf meinen Ansichtsmodell-Validatoren in mein Domänenprojekt zu bringen.
quelle
quelle
set
Teil der Update-Anweisung.Nur um der Liste der Optionen hinzuzufügen. Sie können das Objekt auch aus der Datenbank abrufen und ein Auto-Mapping-Tool wie Auto Mapper verwenden , um die Teile des Datensatzes zu aktualisieren, die Sie ändern möchten.
quelle
Abhängig von Ihrem Anwendungsfall gelten alle oben genannten Lösungen. So mache ich es aber normalerweise:
Für serverseitigen Code (z. B. einen Stapelprozess) lade ich normalerweise die Entitäten und arbeite mit dynamischen Proxys. Normalerweise müssen Sie in Batch-Prozessen die Daten zum Zeitpunkt der Ausführung des Dienstes trotzdem laden. Ich versuche, die Daten stapelweise zu laden, anstatt die Suchmethode zu verwenden, um Zeit zu sparen. Je nach Prozess verwende ich eine optimistische oder pessimistische Parallelitätskontrolle (ich verwende immer optimistisch, außer bei Szenarien mit paralleler Ausführung, in denen ich einige Datensätze mit einfachen SQL-Anweisungen sperren muss, dies ist jedoch selten). Je nach Code und Szenario kann die Auswirkung auf nahezu Null reduziert werden.
Für clientseitige Szenarien haben Sie einige Optionen
Verwenden Sie Ansichtsmodelle. Die Modelle sollten eine Eigenschaft UpdateStatus haben (unverändert-eingefügt-aktualisiert-gelöscht). Es liegt in der Verantwortung des Clients, abhängig von den Benutzeraktionen (Einfügen-Aktualisieren-Löschen) den richtigen Wert für diese Spalte festzulegen. Der Server kann entweder die Datenbank nach den ursprünglichen Werten abfragen, oder der Client sollte die ursprünglichen Werte zusammen mit den geänderten Zeilen an den Server senden. Der Server sollte die ursprünglichen Werte anhängen und die UpdateStatus-Spalte für jede Zeile verwenden, um zu entscheiden, wie mit den neuen Werten umgegangen werden soll. In diesem Szenario verwende ich immer optimistische Parallelität. Dies führt nur die Anweisungen zum Einfügen - Aktualisieren - Löschen und keine Auswahl aus. Möglicherweise ist jedoch ein cleverer Code erforderlich, um das Diagramm zu durchlaufen und die Entitäten zu aktualisieren (abhängig von Ihrem Szenario - Anwendung). Ein Mapper kann helfen, behandelt aber nicht die CRUD-Logik
Verwenden Sie eine Bibliothek wie breeze.js, die den größten Teil dieser Komplexität verbirgt (wie in 1 beschrieben), und versuchen Sie, sie an Ihren Anwendungsfall anzupassen.
Ich hoffe es hilft
quelle