【问题标题】:WPF MVVM master-detail collections with Entity Framework带有实体框架的 WPF MVVM 主从集合
【发布时间】:2013-04-03 10:45:50
【问题描述】:

我在 WPF 中有 2 个组合框,都绑定到 ViewModel 下的 ObservableCollections:

<ComboBox ItemsSource="{Binding Companies}" SelectedItem="{Binding Path=SelectedCompany,Mode=TwoWay}" />
<ComboBox ItemsSource="{Binding Employees}" SelectedItem="{Binding Path=SelectedEmployee,Mode=TwoWay}" />

在 ViewModel 我有:

Public Property Companies As ObservableCollection(Of Company)
Public Property Employees As ObservableCollection(Of Employee)
Public Property SelectedCompany As Company
Public Property SelectedEmployee As Employee

在初始化 ViewModel 时,我询问存储库中的所有公司(它本身使用 Linq-to-Entities 查询),它将公司返回为 IEnumerable (Of Company):

Public Sub New()    
    Companies = New ObservableCollection(Of Company)(_CompanyRepo.GetAll())
End Sub

到目前为止,一切正常。但现在我需要将数据获取到Employees 集合(有一个存储库,它也返回IEnumerable)并且随时只需要所选公司的Employees 数据。

如何在 ViewModel 中执行此操作?员工组合框应在公司组合框中的 SelectedItem 更改时自行更新。

Company 和 Employee 在实体框架中具有一对多的关系。我能以某种方式利用这个事实吗?我可以通过缓存数据来避免以某种方式重复 Linq-to-Entity 查询吗?

【问题讨论】:

    标签: wpf mvvm entity-framework-4 master-detail


    【解决方案1】:

    您可以绑定到实体框架的导航属性。为 Company 组合框使用可观察的集合,并将员工组合框绑定到导航属性。

    所以在 ViewModel 中你只需要:

    Public Property Companies As ObservableCollection(Of Company)
    Public Property SelectedCompany As Company
    Public Property SelectedEmployee As Employee
    

    假设您的实体框架在名为 company_employee 的公司实体上有一个导航属性。您可以直接绑定到您的视图中,例如:

    <ComboBox ItemsSource="{Binding SelectedCompany.company_employee}" SelectedItem="{Binding Path=SelectedEmployee,Mode=TwoWay}" />
    

    WPF 和实体框架将为您获取所需的数据。并且只有拥有匹配公司的员工。

    我所做的是使用用户控件作为我的视图,并有一个网格/用户控件/内容控件,它将绑定(设置其数据上下文)到我的视图中的 SelectedCompany。

    <ContentControl Name="DetailControl" DataContext="{Binding Path=SelectedCompany, Mode=TwoWay}" >
    

    然后,如果您仍然想要一个 selectedemployee 绑定,那么在该 contentcontrol 中,combox 或 datagrid 或 listview 的绑定如下:

    <ComboBox ItemsSource="{Binding company_employee}" SelectedValue="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.SelectedEmployee}" />
    

    但如果您不需要 selectedEMployee,您可以绑定到 company Table 中的 EMployeeID,如下所示:

    <ComboBox ItemsSource="{Binding company_employee}" SelectedValue="{Binding EmplyeeID, Mode=TwoWay" />
    

    您只需直接绑定到导航属性并使用员工外键。

    我刚刚输入了这些,因此您可能需要仔细检查所有名称等。 希望这些选项有所帮助

    编辑 1:

    包含示例(在 vb.net 中)

     Dim MyQuery As IQueryable(Of Company) = CType((From MyResults In Context.Company.Include("Employee") Select MyResults), IQueryable(Of Company))
    

    见:Include Method MSDN Documentation

    【讨论】:

    • 好的。这是否有效,我的意思是每次更改 SelectedCompany 时都不会命中数据库,假设相应的员工数据已经加载一次? (不幸的是,我无法在这里分析数据库查询)
    • 我想这取决于您为什么不想要数据库命中。如果您有 1000 条记录并且您的用户只与其中几条记录进行交互,那么您的数据库只会被命中几次,但如果您想在初始查询时加载导航属性,您可以使用 include 方法来实现。查看包含选项的编辑答案。
    猜你喜欢
    • 2013-06-20
    • 2012-09-02
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多