3 Stimmen

Überschreiben Sie DbContext SaveChanges

Ich benutze EF 4.3.1 Ich muss einen Standardwert einer Entität beim Speichern hinzufügen.

Im Moment benutze ich SaveChanges() und es funktioniert.

Wie Sie aus dem Code sehen können, benutze ich ChangeTracker.Entries() wo Option einen spezifischen Datentyp darstellt.

Ich möchte wissen, ob es möglich ist und wie man eine allgemeinere Version von ChangeTracker.Entries schreibt, so etwas wie ChangeTracker.Entries(), damit es alle Arten von Entitäten in meinem Modell überprüfen kann. In meinem speziellen Fall habe ich eine NoteInternal-Eigenschaft in vielen Klassen.

      public override int SaveChanges()
    {
        #region Option BL
        var entities = ChangeTracker.Entries()
                                    .Where(e => e.State == EntityState.Added ||
                                                e.State == EntityState.Modified)
                                    .Select(e => e.Entity);
        // Standardwerte hinzufügen, wenn eine Entität erstellt oder bearbeitet wird
        string defaultvalue = "";
        foreach (var entity in entities)
        {
            if (String.IsNullOrWhiteSpace(entity.NoteInternal))
                entity.NoteInternal = defaultvalue;
        }
        #endregion

        return base.SaveChanges();
    }

Vielen Dank für Ihre Hilfe!

PS: Macht es hier Sinn, den DYNAMISCHEN Datentyp zu verwenden?

4voto

Anders Abel Punkte 65873

Ich kann mir drei Optionen vorstellen:

  1. Verwenden Sie Reflection, um zu überprüfen, ob jedes Element eine NoteInternal-Eigenschaft hat. Das ist langsam.
  2. Verwenden Sie dynamic, um zu versuchen, auf die NotIntenral-Eigenschaft jedes Elements zuzugreifen. Sie müssen die Ausnahme überprüfen und behandeln, die auftritt, wenn die Entität die Eigenschaft nicht hat.
  3. Erstellen Sie eine Schnittstelle IHasNoteInternal, die die Eigenschaft definiert, und lassen Sie alle Entitäten, die die Eigenschaft haben, diese Schnittstelle implementieren. Holen Sie sich dann alle Einträge vom Typ IHasNoteInternal.

Ich denke, dass die 3. Option am besten ist und das beste Design bietet, aber sie erfordert, dass Sie die Entitäten ändern, was möglicherweise nicht möglich ist. Ich weiß nicht, ob Sie die generische Methode Entries() verwenden können, um die geänderten Entitäten zu erhalten - es könnte fehlschlagen, die Entitäten anhand einer Schnittstelle abzugleichen. Verwenden Sie in diesem Fall die nicht-generische Methode Entries() und verwenden Sie den OfType()-Operator von Linq, um die relevanten Einträge herauszufiltern.

var hasNotInternal = ChangeTracker.Entries()
                     .Select(e => e.Entity).OfType();

1voto

Bob Vale Punkte 17549

Machen Sie Ihre Einträge von einer Schnittstelle erben, die eine NoteInternal-Eigenschaft implementiert.

Erstellen Sie eine Erweiterungsklasse

public static class DbChangeTrackerExtensions {
public static IEnumerable TypedEntries(this DbChangeTracker tracker) {
  return tracker.Entries().OfType();
}

Dann können Sie sie aufrufen und diese Schnittstelle übergeben.

Oder wenn das Ändern der Entitäten nicht möglich ist

var name="NoteInternal";

var entities = ChangeTracker.Entries()  
                                .Where(e => e.State == EntityState.Added ||  
                                            e.State == EntityState.Modified)  
                                .Where(e => e.CurrentValues.Any(c=>c.Name==name && string.IsNullOrWhiteSpace((string)c.CurrentValue)));  
    // Standardwerte hinzufügen beim Erstellen oder Bearbeiten einer Entität  
    string standardwert = "";  
    foreach (var entity in entities)  
    {  
       entity.Property(name).CurrentValue=standardwert;
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X