这是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
绑定到AllSalesOrderNumbers
,SelectedValue
绑定到SelectedOrderNumber
(带Mode=OneWayToSource
)。另一方面,Grid的DataContext绑定到SelectedOrder
。整个工作正常。
我的问题是关于新销售订单按钮。要添加新记录,请在我的ViewModel中添加ICommand
,基本上执行以下操作:
Dim NewOrder = context.SalesOrders.CreateObject()
context.SalesOrders.AddObject(NewOrder)
mSelectedOrderNumber = NewOrder.orderNumber
AllSalesOrderNumbers.Add(mSelectedOrderNumber)
我对以下内容感到困惑:
SelectedOrder
在模型中查询SelectedOrderNumber属性的当前值。由于DB尚未拥有此新记录,因此返回null。在进入数据库之前,如何让它查看本地上下文对象?
与DataSet不同,它不会向orderNumber
分配负增值标识值,所以我想知道如果我添加另一个订单将会发生什么。
在上面第2行(context.SalesOrders
)执行后,我在context.SalesOrders.AddObject(NewOrder)
集合中看不到新添加的订单对象。
答案 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
。因此,视图模型无法了解数据层的技术细节。