Если вы запускаете миграцию сущности (автоматическую или явную) в отношении таблиц, опубликованных для репликации SQL Server, вы получаете следующую ошибку:
Вы можете указать только блокировку READPAST в READ COMMITTED или Уровни изоляции REPEATABLE READ
Ранее были вопросы об этом (здесь), но они полностью не справляются с основной причиной: миграция Entity Framework выполняется на уровне изоляции Serializable
(как это четко видно в профилировщике SQL Server).
Это безопасный выбор для транзакции, изменяющей структуру, но он просто несовместим с опубликованными таблицами SQL Server. В отличие от уровня READ COMMITED SNAPSHOT по умолчанию, используемого в транзакциях dbContext.SaveChanges()
, я еще не нашел способ установить другой уровень изоляции для переноса в коде:
-
TransactionScope
(классический способ установить уровень изоляции для транзакций), по-видимому, игнорируется во времяDatabase.Initialize()
-
Недавно введенный
Database.BeginTransaction(isolationLevel)
фактически пытается инициализировать базу данных до начала новой транзакции, поэтому ее нельзя использовать.
Известные временные решения
-
Сгенерировать все миграции в SQL script. Это работает, но миграция на основе кода - это мощный инструмент, который я бы не хотел пропустить.
-
Используйте явные миграции и запускайте каждый метод
Up()
иDown()
с чем-то вродеSql ( "заданный уровень изоляции транзакции прочитан" );
Это работает, но неудобно и подвержено ошибкам, поскольку разработчики обычно не работают с реплицированной базой данных.