Почему Entity Framework не использует ReadUncommitted для моего второго запроса? - PullRequest
1 голос
/ 27 мая 2019

Мы используем Entity Framework 6 и запрашиваем базу данных с помощью async.

У нас также есть интеграционный тест, запускающий код и для которого мы установили;

  • Тест выполняетсяв транзакции, т. е. мы начинаем наш запуск с begin и заканчиваем его откатом
  • . Данные устанавливаются перед запросами
  • Все они выполняются для одного и того же dbContext
  • IsolationLevelустановлено значение ReadUncommitted

Код:

var table1Id = await _dbContext.Table1.Where(x => x.IdentificationNumber == identificationNumber)
        .Select(y => y.Id)
        .SingleOrDefaultAsync().ConfigureAwait(false);

var table2Id = await _dbContext.Table2.Where(y => y.Table1Id == table1Id)   
        .Select(y => y.Id)
        .FirstOrDefaultAsync().ConfigureAwait(false);

//Code continues...

При чтении базы данных в SSMS с использованием T-SQL и подсказка NOLOCK показывает данные в таблицах.

Запуск моего кода выполняет оба запроса;первый выполняется правильно и возвращает table1Id, как и ожидалось, НО второй не возвращает никакого значения.Похоже, что не работает звонить дважды подряд?Если я переключу порядок, это будет table1Id, который не будет инициирован ни с каким значением.

Если я не использую async / await, то это тоже работает.

У кого-нибудь есть хорошее объяснение этому поведению?Я делаю это неправильно?

РЕДАКТИРОВАТЬ:

public async Task<List<Table4>> GetTable4ListAsync(string key)
{
    var table1Id = await _dbContext.Table1.Where(x => x.Status == Status.Ready)
                    .OrderByDescending(x => x.Id).Select(y => y.Id).FirstOrDefaultAsync().ConfigureAwait(false);

    //more code...

    var table2Id = await _dbContext.Table2.Where(x => x.Key == key).Select(y => y.Id)
        .SingleOrDefaultAsync()
        .ConfigureAwait(false);

    var table3Id = await _dbContext.Table3
        .Where(y => y.Table2Id == table2Id &&
                    y.Table1Id == table1Id)
        .Select(y => y.Id).FirstOrDefaultAsync().ConfigureAwait(false);

    //more code...

    var result = await _dbContext.Table4
        .Where(x => x.Table3.Id == table3Id).ToListAsync()
        .ConfigureAwait(false);

    return result;
}

Выше код близок к нашему фактическому коду.

Когда код выполняется винтеграционный тест внутри транзакции;

  1. запуск транзакции
  2. настройка тестовых данных
  3. запуск теста
  4. откат транзакции

На шаге 3 только первый запрос возвращает результат независимо от порядка.

  • Использование уровня изоляции ReadUncommitted
  • Использование TransactionScopeAsyncFlowOption включено
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...