【问题标题】:Using Linq SubmitChanges without TimeStamp and StoredProcedures the same time同时使用没有 TimeStamp 和 StoredProcedures 的 Linq SubmitChanges
【发布时间】:2009-07-13 09:32:59
【问题描述】:

我正在使用没有 rowversion 或时间戳的 Sql 表。但是,我需要使用 Linq 来更新表中的某些值。由于 Linq 无法知道要更新哪些值,因此我使用第二个 DataContext 从数据库中检索当前对象,并同时使用数据库和实际对象作为 Attach 方法的输入,如下所示:

Public Sub SaveCustomer(ByVal cust As Customer)
    Using dc As New AppDataContext()
        If (cust.Id > 0) Then
            Dim tempCust As Customer = Nothing

            Using dc2 As New AppDataContext()
                tempCust = dc2.Customers.Single(Function(c) c.Id = cust.Id)
            End Using

            dc.Customers.Attach(cust, tempCust)
        Else
            dc.Customers.InsertOnSubmit(cust)
        End If

        dc.SubmitChanges()
    End Using
End Sub

虽然这确实有效,但我有一个问题:我也在使用 StoredProcedures 在某些时候更新 Customer 的某些字段。现在想象以下工作流程:

  1. 从数据库中获取客户
  2. 将客户字段设置为新值
  3. 使用存储过程更新另一个客户字段
  4. 调用 SaveCustomer

现在发生的情况是,SaveCustomer 方法从数据库中检索当前对象,该对象不包含代码中设置的值,但包含存储过程设置的值。将其与实际对象附加然后提交时,它将更新数据库中代码中设置的值,并且... tadaaaa... 将另一个设置为 NULL,因为实际对象不包含由存储过程。

这可以理解吗?

有解决这个问题的最佳实践吗?

【问题讨论】:

    标签: linq stored-procedures timestamp datacontext submitchanges


    【解决方案1】:

    如果您在 ORM 背后进行更改,并且不使用并发检查 - 那么您将遇到问题。您没有显示您在步骤“3”中所做的事情,但 IMO 您应该更新对象模型以反映这些更改,可能使用OUTPUT TSQL 参数。或者;坚持面向对象。

    当然,在没有并发检查的情况下进行任何操作 是丢失数据的好方法 - 所以我的首选 选项只是“添加rowversion”。否则,您也许可以读取更新后的对象并合并内容...以某种方式猜测正确的数据是什么...

    【讨论】:

    • 这听起来很合理。但是,我正在处理客户的数据库和基础架构,他不会引入行版本控制,因为他的数据库的大部分部分是动态生成的,并且他使用自己的框架来访问它。但是,我借此机会与 Linq 一起使用静态表来展示 Linq 的全部内容。 ;-) 现在我遇到了由于 SP 的问题。你有一个很好的资源可以让我了解这种情况下的并发检查吗?
    【解决方案2】:

    如果您要将对象从一个上下文断开并使用另一个上下文进行更新,您需要保留原始对象,使用行版本,或者在数据库中实现某种散列例程并保留散列作为对象的一部分。其中,我强烈推荐 Rowversion 选项。像您尝试做的那样使用当前值作为原始值只是要求并发问题。

    【讨论】:

    • 问题是 - 如上所述 - 我无法添加 rowversioning,因为我正在处理客户数据库并且根本没有修改它的选项。 :(
    猜你喜欢
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多