Использование Linq SubmitChanges без TimeStamp и StoredProcedures одновременно - PullRequest
1 голос
/ 13 июля 2009

Я использую таблицы 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, поскольку фактический объект не содержит изменений, сделанных хранимая процедура.

Это было понятно?

Есть ли лучшая практика для решения этой проблемы?

Ответы [ 2 ]

0 голосов
/ 31 июля 2009

Если вы собираетесь отключить ваш объект от одного контекста и использовать другой для обновления, вам нужно либо сохранить исходный объект, использовать строковую версию, либо реализовать какую-либо процедуру хеширования в вашей базе данных и сохранить хэш как часть вашего объекта. Из них я очень рекомендую вариант Rowversion. Использование текущего значения в качестве исходного значения, которое вы пытаетесь сделать, требует только проблем с параллелизмом.

0 голосов
/ 13 июля 2009

Если вы внесете изменения за заднюю часть ORM и не используете проверку параллелизма - тогда у вас будут проблемы. Вы не показываете, что вы делали на шаге «3», но IMO вы должны обновить объектную модель, чтобы отразить эти изменения, возможно, используя OUTPUT параметры TSQL. Или же; придерживаться объектно-ориентированного.

Конечно, выполнение чего-либо без проверки параллелизма - хороший способ потерять данные - поэтому мой предпочтительный вариант - просто "добавить rowversion". В противном случае, вы могли бы, возможно, прочитать обновленный объект и объединить вещи ... каким-то образом угадав, что это за правильные данные ...

...