我有一个使用 MVVM 模型和实体框架 5 进行数据访问的 WPF 应用程序。我有一个用户控件,其中包含员工的主/详细视图。员工列表的列表视图和“详细信息”网格,其数据上下文设置为列表视图的选定员工。在该网格中,我有一个数据网格,它绑定到所选员工的导航属性(名为employee_certification 的属性)。所有绑定都正常工作并且没有错误,即使在输出窗口中也是如此。
问题:我的问题是我无法检测到用户是否对导航属性的记录进行了任何更改。我目前使用更改跟踪器来测试实体中的更改以启用某些命令按钮,例如保存、撤消等。但是更改跟踪器从未检测到导航属性(称为雇员认证)中的更改。
以下是我从模型中获取员工实体的方法:
Public Function GetEmployee_All(Context As FTC_Context) As ObservableCollection(Of employee) Implements IEmployeeDataService.GetEmployee_All
Dim employees = Context.employees.Include("employee_certification").ToList
Return New ObservableCollection(Of employee)(employees)
End Function
这是导航属性到数据网格的绑定。(有效,这意味着它确实显示了正确的记录)
<DataGrid Grid.Column="1" Grid.Row="2" MinWidth="350"
ItemsSource="{Binding ElementName=DetailControl, Mode=TwoWay, Path=DataContext.employee_certification}"
CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
</DataGrid.Columns>
</DataGrid>
即使绑定有效并且显示了正确的记录,我也无法确定用户是否对导航属性的记录进行了更改。
目标:如果可能的话,我希望能够通过上下文本身检测变化。我不想编写一个帮助类来将当前记录与数据库原件进行比较。有人可以帮我这样做吗?
编辑#1: 我认为这可能与数据网格有关。我在我的应用程序的另一个用户控件中有以下列表视图,并且可以通过 EF 上下文跟踪对列表视图记录中的记录字段所做的任何更改。
绑定 vendor_account 是实体 vandor 的导航属性的列表视图:
<ListView Grid.Column="1" Grid.Row="2"
Style="{DynamicResource FTC_SubListView}"
ItemContainerStyle="{DynamicResource FTC_SubListViewItem}"
ItemsSource="{Binding vendor_account, Mode=TwoWay}"
ItemTemplate="{DynamicResource FTC_VendorAccountsTemplate}" />
以下是我如何确定是否有更改以在我的视图中启用保存按钮:
Private Function CanSaveExecute() As Boolean
If _Selection.HasErrors = False Then
If (From entry In Context.ChangeTracker.Entries(Of vendor)() Where entry.Entity.idVendor = _Selection.idVendor And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
ElseIf (From entry In Context.ChangeTracker.Entries(Of vendor_account)() Where entry.Entity.idVendor = _Selection.idVendor And (entry.State = EntityState.Modified Or entry.State = EntityState.Added) Select entry).Count > 0 Then
Return True
Else
Return False
End If
Else
Return False
End If
End Function
但如果我对数据网格使用以下内容,它永远不会对emplopyee_certification 导航属性进行更改计数:
Private Function CanSaveExecute() As Boolean
If _Selection.HasErrors = False Then
If (From entry In Context.ChangeTracker.Entries(Of employee)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
ElseIf (From entry In Context.ChangeTracker.Entries(Of employee_certification)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count > 0 Then
Return True
Else
Return False
End If
Else
Return False
End If
End Function
有谁知道为什么我的列表视图允许更改跟踪器从更改跟踪器中查看 x 个已更改的实体,但不能使用数据网格?
编辑#2
好的,所以我缩小范围,我将列表视图和数据网格放在同一个用户控件上,并以相同的方式将它们绑定到对象的数据上下文的导航属性,如上所述。员工具有作为链接记录的认证,这是员工对象的导航属性 (employee_certification)。
如果我对employee_certification 记录使用列表视图,那么当我对这些记录进行更改时,我可以查询更改跟踪器以计算更改并在计数大于零时启用保存和撤消按钮。
From entry In Context.ChangeTracker.Entries(Of employee_certification)() Where entry.Entity.idEmployee = _Selection.idEmployee And entry.State = EntityState.Modified Select entry).Count
当我使用数据网格并更改employee_certification 记录中的任何字段时,更改跟踪器不会将其中任何一个标记为已修改。
这是数据网格/列表视图的定义方式
<DataGrid Grid.Column="1" Grid.Row="2" MinWidth="350"
ItemsSource="{Binding employee_certification, Mode=TwoWay}"
CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
<!-- Custom Defined Columns Go Here -->
</DataGrid.Columns>
</DataGrid>
<ListView Grid.Column="1" Grid.Row="3"
Style="{DynamicResource FTC_SubListView}"
ItemContainerStyle="{DynamicResource FTC_SubListViewItem}"
ItemsSource="{Binding employee_certification, Mode=TwoWay}"
ItemTemplate="{DynamicResource MyTemplate}">
</ListView>
由于内置排序等,我想使用数据网格。
编辑问题#2:为什么更改跟踪器跟踪列表视图编辑中的更改而不是数据网格编辑?