У меня проблема с EF6, использующим подход Code-First, когда новый контекст БД, пытающийся получить доступ к объекту, вызывает исключение нулевой ссылки. Вот пример моего сценария:
Основная нить
int personId = 0;
using(var ctx = new exampleContext())
{
var person = new Person() {Name = "Alex"};
ctx.People.Add(person);
ctx.SaveChanges();
personId = person.id;
}
Task.Run(() => {someOtherThread(personId)})
Другая тема
public static someOtherThread(int personId)
{
using(var ctx = new exampleContext())
{
var person = ctx.People.Where(x => x.id == personId);
//Exception here.
var name = person.Name;
}
}
Когда я отключаю опцию Is Read Committed Snapshot в БД, это работает как положено (по умолчанию, когда EF создает БД), но мы хотим поддерживать максимально оптимистичную модель управления параллелизмом.
Я думаю, что происходит то, что SaveChanges не ожидает создания нового снимка в базе данных, и в результате другой поток читает старый снимок.
Обратите внимание, что если я сплю потоку, пока он не может получить запись, это в конечном итоге произойдет, поэтому SaveChanges не завершится сбоем.
Есть что-то, чего я здесь не хватает? Это возможная ошибка с EF или это работает как ожидалось? Если это работает, как ожидалось, какова лучшая практика, чтобы обойти это?
Спасибо!