Подтвердить что ты не робот

Как установить уровень изоляции для Entity Framework CodeFirst Migrations

Если вы запускаете миграцию сущности (автоматическую или явную) в отношении таблиц, опубликованных для репликации 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 ( "заданный уровень изоляции транзакции прочитан" );

Это работает, но неудобно и подвержено ошибкам, поскольку разработчики обычно не работают с реплицированной базой данных.

4b9b3361

Ответ 1

Помогло бы вам создать свой onm-Migrator?

internal sealed class Configuration : DbMigrationsConfiguration<SupplierEntities>
{
  public Configuration()
  {
    SetSqlGenerator("System.Data.SqlClient", new SqlMigrator());
  }

  private class SqlMigrator : SqlServerMigrationSqlGenerator
  {
    public override IEnumerable<MigrationStatement> Generate(
      IEnumerable<MigrationOperation> migrationOperations, string providerManifestToken)
    {
      yield return new MigrationStatement { Sql = "set transaction isolation level read committed" };
      foreach (var statement in base.Generate(migrationOperations, providerManifestToken))
        yield return statement;
    }
  }
}