WPF and EF6 mark model entity as having chnages


Question

Background: I have a wpf 4.5 application that is built with MVVM (MVVM-Light) and Enitity Framework 6 db first.

I have several viewmodels that have a list/details set up with a list of objects in a listbox and a details grid that displays and allows the user to edit the selected record of the listbox. I have a SAVE and UNDO button at the top of the grid that I want to "enable" when there are changes to the underlying model entity of the selected record.

I am able to do this but the performance of my current solution is terrible and I need a new strategy to detect changes in my model.

What I Have Now:

I have a CanSaveExecute method that is the CanExecute Callback of an ICommand Object. IN that method I query the EF dbContext ChangeTracker Entities to see if any objects of my desired type are present.

 Try
    If _Selection IsNot Nothing AndAlso _Selection.HasErrors = False Then
         Return (From entry In Context.ChangeTracker.Entries(Of job)() Where entry.Entity.idJob = _Selection.idJob And entry.State = EntityState.Modified Select entry).Count
    Else
         Return False
    End If
 Catch ex As Exception
    Return False
 End Try

The problem is that this query of the change tracker entries is destroying the UI performance. It causes serious lag with user input.

My Question:

Does someone have a better strategy for detecting changes in a CanExecute method with Entity Framework 6? Preferably without changing the T4 codee (but I have a feeling this is where I will end up).


More Detail:

Here is how my model is set up. EF6 generates a simple entity class for me that looks like this (I removed a lot of properties to keep it simple as an example) :

Imports System
Imports System.Collections.Generic

Partial Public Class job
    Public Property idJob As Integer
    Public Property idLinkedJob As Nullable(Of Integer)
    Public Property idStatus As Byte
    Public Property idEstimate As Nullable(Of Integer)
    Public Property chrTitle As String

    Public Overridable Property alerts As ICollection(Of alert) = New HashSet(Of alert)
    Public Overridable Property client As client
End Class

I extend that class with another partial class to add datavalidation rules like this (again, simplified for example) :

Partial Public Class job
    Inherits ValidationBase

#Region "PROPERTIES"
    Public Property HasChanges As Boolean = False
#End Region

#Region "CONSTRUCTORS"
    Public Sub New()
        ''default values
        Me.FTC_Type = 4
        Me.dtCreated = Now
        Me.dtUpdated = Now
        'HasChanges = False
    End Sub

    Public ReadOnly Property DisplayPath
        Get
            Return "W" + idJob.ToString + ": " + chrTitle + " - " + client.chrCompany
        End Get
    End Property
#End Region

#Region "VALIDATION FUNCTIONS"

    Public Overrides Function Validate(validationContext As ComponentModel.DataAnnotations.ValidationContext) As IEnumerable(Of ComponentModel.DataAnnotations.ValidationResult)
        Return MyBase.Validate(validationContext)
        PropertyValitaion(True)
    End Function

    Public Sub PropertyValitaion(bAllProperties As Boolean, Optional sProperty As String = "")
        'initialize validation helper

        If bAllProperties OrElse sProperty = "chrTitle" Then
            If String.IsNullOrEmpty(chrTitle) Then
                AddError("chrTitle", "You must enter a Job Title")
            Else
                RemoveError("chrTitle")
            End If
        End If
        If bAllProperties OrElse sProperty = "idClient" Then
            If idClient < 1 Then
                AddError("idClient", "You must select a job client")
            Else
                RemoveError("idClient")
            End If
        End If

        If String.IsNullOrEmpty(sProperty) = False Then
            OnPropertyChanged(sProperty)
        End If

    End Sub
#End Region
End Class

No solution:

So after fighting with it for a day I've decided that @Shoe is right. Its turned out to be too much work for this feature. I could never get a call to the change tracker to not cause UI lag.

Popular Answer

I'm just not seeing any advantages to the changes MS has made to Entity Framework. The classes no longer support change tracking and querying if there are changes is many times slower than using dbcontext. I wish they had documented all these changes better so I wouldn't have wasted so much time trying to get this to work.

Btw, if I use a viewmodel and let's say I have product entity with sixty fields. How do the changes on those fields get propagated back to the model?





Licensed under: CC-BY-SA
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why