2016-06-01 7 views
0

über Proxies in EF6.1.3 mit dem folgenden Code (VB.NET) modifiziert: -EF-Kennzeichnung Entitäten als ohne Änderungen

Dim DB As New BMContext 

Dim sl = DB.StockLevels.First 
Dim ee = (From e In DB.ChangeTracker.Entries Where e.Entity Is sl).Single 
sl.Level = sl.Level 

prüfen ee.State vor der letzten Zeile gibt richtig einen Zustand von unmodifizierten. Nach dieser Zeile wird es als Modifiziert angezeigt, obwohl die Eigenschaft auf das festgelegt wurde, was sie bereits war. Dies löst sogar ein UPDATE aus, wenn ich SaveChanges aufruft!

Datenklasse Code: -

Public Class StockLevel 
    Public Overridable Property ID As Integer 
    Public Overridable Property Level As Integer? 
End Class 

Offensichtlich ist meine eigentliche Code eher viel komplexer als dieses Beispiel ziemlich sinnlos andere ist das Problem als zu demonstrieren.

+0

Wie dieser Beitrag schlägt vor, Sie können am Ende eine Menge Code hinzufügen. http://codereview.stackexchange.com/questions/37304/update-only-modified-fields-in-entity-framework –

Antwort

1

"Change-Tracking-Proxies markieren eine Eigenschaft als modifiziert, wenn ein Wert darauf geschrieben wird."

Von source

Grundsätzlich, da Sie einen Wert dieser Eigenschaft sind die Zuordnung (auch wenn es genau die gleiche Wert ist), können Sie einen Modified Zustand erhalten.

+0

Das scheint mir wirklich Müll zu sein. Sollte es vor der Durchführung des UPDATE nicht zumindest nochmal überprüft werden? – wizzardmr42

+0

Sie finden [http://codepaq.blogspot.com/2014/09/entity-framework-update-only-changed.html] interessant. Ich weiß, dass es C# ist, aber Sie können sehen, was sich ziemlich klar abspielt. Es gibt auch einen anständigen Artikel über [msdn blogs] (http://blogs.msdn.com/b/adonet/archive/2011/02/09/self-tracking-entities-original-values-and-update-customization. Aspx) diesbezüglich. Ich bin mir nicht sicher, was ich Ihnen sagen soll, abgesehen von verschiedenen Möglichkeiten, die Change-Tracking-Konfiguration zu implementieren oder zu überschreiben. Sie können 'AsNoTracking' auch aus der' DbQuery 'Klasse verwenden. –

+0

Das ist ein etwas anderes Problem - in dieser Situation werden alle Felder aktualisiert statt einiger. Ich habe es mit einer Situation zu tun, in der in vielen Fällen keine aktualisiert werden sollte. Ich habe Code geschrieben, um es in einer Antwort selbst zu beheben, aber es scheint lächerlich, dass dies notwendig ist - Linq to SQL handhabt das viel besser. AsNoTracking hilft mir in diesem Fall nicht, denn wenn ich die Daten anfange, werden alle Ergebnisse zusammengemischt und ich weiß nicht einmal, welche sich geändert haben, bis ich sie verarbeitet habe. – wizzardmr42

0

Ich habe dies am Ende zu schreiben, bevor Savechanges zu nennen, obwohl ich es ein bisschen lächerlich finde, dass ich brauche ...

Public Class DbEntityModification 

    Public ReadOnly Property FieldName As String 
    Public ReadOnly Property OriginalValue As Object 
    Public ReadOnly Property CurrentValue As Object 

    Public Sub New(FieldName As String, OriginalValue As Object, CurrentValue As Object) 
     _FieldName = FieldName 
     _OriginalValue = OriginalValue 
     _CurrentValue = CurrentValue 
    End Sub 

End Class 

<Extension()> Public Function GetChangedValues(e As DbEntityEntry) As IDictionary(Of String, DbEntityModification) 

    Dim ret As New Dictionary(Of String, DbEntityModification) 

    For Each propname In e.CurrentValues.PropertyNames 
     Dim nv = e.CurrentValues.Item(propname) 
     Dim ov = e.OriginalValues.Item(propname) 

     Dim Changed = False 
     If ov Is Nothing Then 
      Changed = nv IsNot Nothing 
     ElseIf Not ov.Equals(nv) Then 
      Changed = True 
     End If 

     If Changed Then 
      Dim m As New DbEntityModification(propname, ov, nv) 
      ret.Add(propname, m) 
     End If 

    Next 
    Return ret 
End Function 

<Extension()> Public Sub MarkUnchangedAnyUnchangedEntities(ees As IEnumerable(Of DbEntityEntry)) 
    For Each ee In ees 
     If ee.State = EntityState.Modified Then 
      If GetChangedValues(ee).Keys.Count = 0 Then 
       ee.State = EntityState.Unchanged 
      End If 
     End If 
    Next 
End Sub 
<Extension()> Public Sub MarkUnchangedAnyUnchangedEntities(context As DbContext) 
    context.ChangeTracker.Entries.MarkUnchangedAnyUnchangedEntities() 
End Sub 
Verwandte Themen