Первый код для SQL Server 2005? - PullRequest
3 голосов
/ 07 марта 2012

Моей базой данных разработки является 2008 R2, где Code First генерирует локальную базу данных с DropCreateIfModelChanges.

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

Работает: Запустите сценарий в другом экземпляре 2008 R2, измените строку подключения для модели Entity, чтобы указать на этот производственный экземпляр, запустите приложение.

не работает: Запустите скрипт в другом экземпляре 2005 года, измените строку подключения для модели Entity, чтобы указать на этот производственный экземпляр, запустите приложение. Я получаю сообщение об ошибке, указывающее, что модель изменилась.

Я думаю, что это не работает, потому что версия совместимости с БД является частью хэша. таким образом, в производстве он генерирует хеш и сравнивает его с хешем, хранящимся в таблице EdmMetadata. Новый хэш отличается тем, что он генерируется для базы данных 2005 года.

Полагаю, у меня не возникло бы этой проблемы, если бы я генерировал базу данных 2005 года локально и развертывал ее в производственном экземпляре 2005 года. Однако у меня нет установленного 2005 года, и я бы предпочел, чтобы все разработчики не устанавливали его, когда 2008 год уже поддерживает режим совместимости с 2005 годом.

Как заставить EF генерировать БД в режиме совместимости 2005 года?

1 Ответ

2 голосов
/ 25 марта 2012

Если единственной проблемой является проверка совместимости модели, то вы можете отключить инициализаторы базы данных для своего контекста при работе в производственной среде, где, по-видимому, вам все равно не нужно инициализировать базу данных.Вы можете сделать это в коде так:

Database.SetInitializer<MyContext>(null);

Но, вероятно, лучше сделать это в app.config / web.config для вашего производственного приложения, например так:

<entityFramework>
  <contexts>
    <context type="MyNamespace.MyContext, MyAssembly" disableDatabaseInitialization="true" />
  </contexts>
</entityFramework>

Вам необходимо обновить EF 4.3 для этого синтаксиса - см. http://blogs.msdn.com/b/adonet/archive/2012/01/12/ef-4-3-configuration-file-settings.aspx.. Есть также способ сделать это в EF 4.1: см. http://blog.oneunicorn.com/2011/03/31/configuring-database-initializers-in-a-config-file/.

. Вы также можете попробовать обновить доEF 4.3, который больше не использует таблицу EdmMetadata - вместо этого она использует таблицу __MigrationHistory.Это проверяет совместимость модели другим способом.Это может по-прежнему помечать разницу, если Code First сгенерировал бы другую базу данных для 2005 года, чем это было в 2008 году, что иногда имеет место.

Вы можете установить SQL Server 2005 Express на своем компьютере разработчика.Это бесплатно и будет лучше соответствовать вашей производственной среде.

Наконец, если ничего из вышеперечисленного не сработало и вам нужно заставить Code First сгенерировать модель / базу данных 2005 года, тогда вы можете это сделать, но это означает использование более низкогостроительные блокиВо-первых, вам нужно создать DbModelBuilder самостоятельно и вызвать Entity для каждого из типов сущностей, для которых у вас есть DbSet, объявленный в вашем контексте:

var modelBuilder = new DbModelBuilder();
modelBuilder.Entity<User>();
modelBuilder.Entity<Blog>();

Вы можете сделать другую свободную конфигурацию здесь или использовать данныеаннотации как обычно.OnModelCreating не будет вызываться, поэтому не делайте там быстрых вызовов - переместите их сюда вместо этого.

Как только у вас будет настроенный DbModelBuilder, вам нужно будет собирать и компилировать, чтобы получить скомпилированную модель, которую можно передатьDbContext.Именно на этом этапе вы можете передать «2005» в качестве токена манифеста провайдера.

var compiledModel = modelBuilder
    .Build(new DbProviderInfo("System.Data.SqlClient", "2005"))
    .Compile();

Теперь вам следует кэшировать эту скомпилированную модель в домене приложения, чтобы ее можно было собрать и скомпилировать только один раз.(Обычно DbContext делает это для вас, когда строит модель, но если вы строите модель самостоятельно, вам также необходимо выполнить кеширование самостоятельно.)

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

public class MyContext : DbContext
{
    public MyContext(DbCompiledModel model)
        : base(model)
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Blog> Blogs { get; set; }
}

Существуют и другие перегрузки конструктора для передачи имени или строки соединения, если они вам нужны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...