【问题标题】:Entity Framework confusions实体框架混淆
【发布时间】:2013-02-24 18:01:00
【问题描述】:

这是 WPF + MVVM + EF。我的数据库中有一张销售订单表。在 UI 中,我显示了一个包含所有 SalesOrderNumbers 的 ComboBox 和一个带有标签和 TextBoxes 的网格,它们显示了 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 

在 UI 中,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)

我对以下内容感到困惑:

  1. SelectedOrder 在模型中查询 SelectedOrderNumber 属性的当前值。由于数据库还没有这个新记录,它返回 null。在去数据库之前,我如何要求它查看本地上下文对象?

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

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

【问题讨论】:

    标签: wpf entity-framework mvvm binding


    【解决方案1】:

    技术答案:

    1.SelectedOrder 向模型查询 SelectedOrderNumber 属性的当前值。由于数据库还没有这个新记录,它返回 null。我如何要求它在访问数据库之前查看本地上下文对象?

    您可以像这样查询DbSet 的本地集合:

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

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

    当您添加新的Orders 时,EF 会将它们中的每一个作为单独的实例进行跟踪。

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

    参见 1。它在 Local 集合中。

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

    【讨论】:

    • 非常感谢。问题是我的 SalesOrder 表有很多列并且可以有数千行。我不想通过将整个表加载到 VM 中来使我的应用程序占用内存。所以我正在做的是最初加载订单号,然后在需要时查询实际行。顺便说一句,我是 WPF + MVVM 世界的新手(来自 Button1_Click 类型的 WinForms 编码)并且已经经历了陡峭的学习曲线,因此此时添加另一层可能对我来说变得难以管理。
    • 好的,我明白了。好吧,Local 集合应该可以。尽管如此,我相信现在在更好的分离架构上投入一些时间会在以后节省时间。您可以让视图模型向控制器发出命令以查询 Id 指定的Orders。
    • 我在我的 SalesOrder 属性中没有看到“本地”成员。我在这里错过了什么?
    • 它是DbContext API(DbSet)的一部分,显然你使用ObjectContext?
    猜你喜欢
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2021-12-14
    • 2022-09-23
    • 2021-08-15
    • 1970-01-01
    • 2012-02-11
    相关资源
    最近更新 更多