После отката транзакции Entity Framework сохраненный в кэше элемент сохраняется - PullRequest
1 голос
/ 23 августа 2011

Я использую контекст Entity Framework и иногда хотел бы создать транзакцию, чтобы клиент мог сделать несколько изменений, а затем зафиксировать / откатить их все вместе. Однако, если было сделано много изменений, и SaveChanges () вызывался несколько раз, после чего вызывался откат, сущности, которые уже были зафиксированы, останутся такими же, как они были зафиксированы, и не будут откатываться.

Вот как выглядят мои функции, относящиеся к транзакциям:

Public Sub BeginTransaction()
    Dim context = HttpContext.Current.GetObjectContext()
    If Not context.Connection.State = ConnectionState.Open Then
        context.Connection.Open()
    End If
    Dim trasnaction = context.Connection.BeginTransaction()
    HttpContext.Current.Items("transaction") = trasnaction
End Sub

Public Sub CommitTransaction()
    Dim transaction = CType(HttpContext.Current.Items("transaction"), DbTransaction)
    transaction.Commit()
    HttpContext.Current.Items("transaction") = Nothing
End Sub


Public Sub RollbackTransaction()
    Dim transaction = CType(HttpContext.Current.Items("transaction"), DbTransaction)
    transaction.Rollback()
    HttpContext.Current.Items("transaction") = Nothing
End Sub

И затем я запускаю следующий тест:

Public Sub TransactionsTest()
    Dim context = GetObjectContext()
    Dim firstString = context.LocalizedStrings.Where(Function(ls) ls.ID = 4).First()
    Dim secondString = context.LocalizedStrings.Where(Function(ls) ls.ID = 5).First()

    Dim firstStringOriginal = firstString.Text
    Try
        DatabaseProvider.BeginTransaction()
        firstString.Text = "blabla"
        context.SaveChanges() //Saves OK
        Dim caughExeption = False
        Try
            secondString.LanguageID = "suka"
            context.SaveChanges() //Doesn't save, because change is invalid
            DatabaseProvider.CommitTransaction()
        Catch ex As Exception
            DatabaseProvider.RollbackTransaction()
            caughExeption = True
        End Try
        Assert.IsTrue(caughExeption)
        // Try to retrieve the first string again
        firstString = context.LocalizedStrings.Where(Function(ls) ls.ID = 4).First()
        Assert.AreEqual(firstStringOriginal, firstString.Text) // FAILS :(
    Finally
        firstString.Text = firstStringOriginal
        context.SaveChanges()
    End Try
End Sub

Любая помощь будет высоко ценится, спасибо.

Мало того, что тест не пройден, но он также оставляет ObjectContext в нестабильном режиме, потому что в нем все еще есть недопустимые изменения.

1 Ответ

4 голосов
/ 23 августа 2011

Это не имеет ничего общего с транзакциями. Так ведет себя EF. Вы используете тот же экземпляр контекста для загрузки объекта => вы получите свой первый (измененный, но не сохраненный) экземпляр объекта, несмотря на данные в базе данных Это происходит из-за базовой концепции ORM под названием идентификационная карта . Если вы хотите получить реальные данные из базы данных, вы должны указать EF перезаписать ваши изменения:

context.LocalizedStrings.MergeOption = MergeOption.OverwriteChanges
firstString = context.LocalizedStrings.Where(Function(ls) ls.ID = 4).First()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...