实体框架的混淆

时间:2013-02-24 18:01:01

标签: wpf entity-framework mvvm binding

这是WPF + MVVM + EF。我的数据库中有一份销售订单表。在UI中,我展示了一个包含所有SalesOrderNumbers的ComboBox和一个带有标签和文本框的网格,它显示了ComboBox中所选订单的详细信息。请考虑以下ViewModel:

Class SalesOrderViewModel
    Public Property AllSalesOrderNumbers As List(Of Integer)

    Public Sub New()
        AllSalesOrderNumbers = context.SalesOrders.Select(Function(x) x.orderNumber).ToList()
        If AllSalesOrderNumbers.Count > 0 Then SelectedOrderNumber = AllSalesOrderNumbers(0)
    End Sub

    Private Property mSelectedOrderNumber As Integer
    Public Property SelectedOrderNumber As Nullable(Of Integer)
        Get
            Return mSelectedOrderNumber
        End Get
        Set(value As Nullable(Of Integer))
            mSelectedOrderNumber = value
        End Set
    End Property

    Public ReadOnly Property SelectedOrder As SalesOrder
        Get
           Return context.SalesOrders.FirstOrDefault(Function(x) x.orderNumber = SelectedOrderNumber)
        End Get
    End Property
End Class 

在用户界面中,ComboBox的ItemsSource绑定到AllSalesOrderNumbersSelectedValue绑定到SelectedOrderNumber(带Mode=OneWayToSource)。另一方面,Grid的DataContext绑定到SelectedOrder。整个工作正常。

我的问题是关于新销售订单按钮。要添加新记录,请在我的ViewModel中添加ICommand,基本上执行以下操作:

Dim NewOrder = context.SalesOrders.CreateObject()
context.SalesOrders.AddObject(NewOrder)
mSelectedOrderNumber = NewOrder.orderNumber
AllSalesOrderNumbers.Add(mSelectedOrderNumber)

我对以下内容感到困惑:

  1. SelectedOrder在模型中查询SelectedOrderNumber属性的当前值。由于DB尚未拥有此新记录,因此返回null。在进入数据库之前,如何让它查看本地上下文对象?

  2. 与DataSet不同,它不会向orderNumber分配负增值标识值,所以我想知道如果我添加另一个订单将会发生什么。

  3. 在上面第2行(context.SalesOrders)执行后,我在context.SalesOrders.AddObject(NewOrder)集合中看不到新添加的订单对象。

1 个答案:

答案 0 :(得分:0)

技术答案:

  

1.SelectedOrder在模型中查询SelectedOrderNumber属性的当前值。由于DB尚未拥有此新记录,因此返回null。在进入DB之前,如何让它查看本地上下文对象?

您可以查询DbSet的本地集合,如下所示:

context.SalesOrders.Local.FirstOrDefault(...)
  

2.与DataSet不同,它没有为orderNumber分配负增量标识值,所以我想知道如果我添加另一个订单将会发生什么。

当你添加新的Order时,EF会将它们作为单独的实例进行跟踪。

  

3.我没有在上面第二行(context.SalesOrders.AddObject(NewOrder))执行后的context.SalesOrders集合中看到新添加的订单对象。

请参阅1.它位于Local集合中。

架构答案:在视图模型中使用context不是最佳选择。视图模型不应该担心它的数据,它应该接收数据,然后是自包含的。它的职责是响应用户交互并将这些信息通知给控制器或服务层。因此,应该使用Order列表填充模型,然后处理上下文。添加新订单时,模型应立即或在保存命令后告诉控制器,并且可能会收到命令(重新)显示Order。因此,视图模型无法了解数据层的技术细节。