c# - tutorial - paging asp net mvc




Entity Framework 5 Aktualisieren eines Datensatzes (5)

Ich habe verschiedene Methoden zum Bearbeiten / Aktualisieren eines Datensatzes innerhalb von Entity Framework 5 in einer ASP.NET MVC3-Umgebung untersucht, aber bisher hat keines von ihnen alle Felder markiert, die ich brauche. Ich werde erklären warum.

Ich habe drei Methoden gefunden, auf die ich die Vor- und Nachteile anführen werde:

Methode 1 - Laden Sie den ursprünglichen Datensatz, aktualisieren Sie jede Eigenschaft

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

Pros

  • 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 - Laden Sie den ursprünglichen Datensatz, legen Sie die geänderten Werte fest

var original = db.Users.Find(updatedUser.UserId);

if (original != null)
{
    db.Entry(original).CurrentValues.SetValues(updatedUser);
    db.SaveChanges();
}

Pros

  • Nur geänderte Eigenschaften werden 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 anfügen und Status auf EntityState.Modified festlegen

db.Users.Attach(updatedUser);
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();

Pros

  • 1 x Abfrage der zu aktualisierenden Datenbank

Nachteile

  • Kann nicht angeben, welche Eigenschaften sich ändern
  • Ansichten müssen jede Eigenschaft enthalten

Frage

Meine Frage an euch; Gibt es einen sauberen Weg, um diese Ziele zu erreichen?

  • Kann angeben, welche Eigenschaften sich ändern
  • Views müssen nicht jede Eigenschaft enthalten (zB Passwort!)
  • 1 x Abfrage der zu aktualisierenden Datenbank

Ich verstehe, dass dies eine ganz kleine Sache ist, auf die ich hinweisen muss, aber vielleicht fehlt mir eine einfache Lösung dafür. Wenn nicht Methode eins wird sich durchsetzen ;-)


Abhängig von Ihrem Anwendungsfall gelten alle oben genannten Lösungen. So mache ich es aber normalerweise:

Bei serverseitigem Code (zB Batch-Prozess) lade ich normalerweise die Entitäten und arbeite mit dynamischen Proxies. In Batch-Prozessen müssen Sie die Daten normalerweise immer zum Zeitpunkt der Ausführung des Service laden. Ich versuche, die Daten im Stapel zu laden, anstatt die Methode find zu verwenden, um etwas Zeit zu sparen. Abhängig vom Prozess verwende ich optimistische oder pessimistische Gleichzeitigkeitskontrolle (ich verwende immer optimistisch, außer für parallele Ausführungsszenarien, wo ich einige Datensätze mit einfachen SQL-Anweisungen sperren muss, dies ist jedoch selten). Je nach Code und Szenario kann der Einfluss auf nahezu Null reduziert werden.

Für clientseitige Szenarien haben Sie einige Optionen

  1. Verwenden Sie Ansichtsmodelle. Die Modelle sollten eine Eigenschaft UpdateStatus (unmodified-inserted-update-deleted) haben. Es liegt in der Verantwortung des Kunden, in Abhängigkeit von den Benutzeraktionen (insert-update-delete) den korrekten 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 umzugehen ist. In diesem Szenario verwende ich immer optimistische Parallelität. Dies führt nur die Anweisungen insert - update - delete und nicht irgendwelche selects aus, aber es kann cleverer Code erforderlich sein, um das Diagramm zu durchlaufen und die Entitäten zu aktualisieren (abhängig von Ihrem Szenario - Anwendung). Ein Mapper kann helfen, aber nicht mit der CRUD-Logik umgehen

  2. 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


Du suchst nach:

db.Users.Attach(updatedUser);
var entry = db.Entry(updatedUser);
entry.Property(e => e.Email).IsModified = true;
// other changed properties
db.SaveChanges();

Ich mag die angenommene Antwort sehr. Ich glaube, es gibt noch einen anderen Weg, dies zu erreichen. Nehmen wir an, Sie haben eine sehr kurze Liste von Eigenschaften, die Sie niemals in eine Ansicht aufnehmen möchten. Beim Aktualisieren der Entität würden diese also weggelassen. Nehmen wir an, dass diese beiden Felder Passwort und SSN sind.

db.Users.Attach(updatedUser);

var entry = db.Entry(updatedUser);
entry.State = EntityState.Modified;

entry.Property(e => e.Password).IsModified = false;
entry.Property(e => e.SSN).IsModified = false;   

db.SaveChanges();   

In diesem Beispiel können Sie Ihre Geschäftslogik im Wesentlichen verlassen, nachdem Sie der Tabelle "Benutzer" und der Ansicht ein neues Feld hinzugefügt haben.


Nur um zur Liste der Optionen hinzuzufügen. Sie können das Objekt auch aus der Datenbank abrufen und ein automatisches Zuordnungswerkzeug wie Auto Mapper verwenden , um die Teile des Datensatzes zu aktualisieren, die Sie ändern möchten.


public interface IRepository
{
    void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class;
}

public class Repository : DbContext, IRepository
{
    public void Update<T>(T obj, params Expression<Func<T, object>>[] propertiesToUpdate) where T : class
    {
        Set<T>().Attach(obj);
        propertiesToUpdate.ToList().ForEach(p => Entry(obj).Property(p).IsModified = true);
        SaveChanges();
    }
}




entity-framework-5