Entity Framework 4.1 Стратегия пользовательского инициализатора базы данных - PullRequest
2 голосов
/ 17 июля 2011

Я хотел бы реализовать собственную стратегию инициализации базы данных, чтобы я мог:

  • создать базу данных, если она не существует
  • , если при изменении модели создаются только новые таблицы
  • при смене модели создайте только новые поля без удаления таблицы и потери данных.

Заранее спасибо

Ответы [ 3 ]

2 голосов
/ 17 июля 2011

Есть причина, по которой этого еще не существует. Это очень сложный интерфейс, и, кроме того, интерфейс IDatabaseInitializer не очень подготовлен к такому (нет способа сделать независимую базу данных инициализации). Ваш вопрос "слишком широк", чтобы ответить на ваше удовлетворение. С вашей реакцией на правильный ответ @ Eranga вы просто ожидаете, что кто-то скажет вам шаг за шагом, как это сделать, но мы не будем - это будет означать, что мы напишем инициализатор для вас.

Что нужно делать, что хочешь?

  • Вы должны очень хорошо знать SQL Server. Вы должны знать, как SQL-сервер хранит информацию о базе данных, таблицах, столбцах и отношениях = вы должны понимать sys представлений, и вы должны знать, как запрашивать их, чтобы получить данные о текущей структуре базы данных.
  • Вы должны очень хорошо знать EF. Вы должны знать, как EF хранит картографическую информацию. Вы должны уметь исследовать метаданные, получать информацию об ожидаемых таблицах, столбцах и отношениях.
  • Если у вас есть старое описание базы данных и новое описание базы данных, вы должны быть в состоянии написать код, который будет корректно исследовать изменения и создавать команды SQL DDL для изменения вашей базы данных. Даже если это выглядит как самая простая часть всего процесса, на самом деле она самая сложная, потому что в SQL-сервере есть много других внутренних правил, которые не могут быть нарушены вашими командами. Иногда вам действительно нужно удалить таблицу, чтобы внести изменения, и если вы не хотите терять данные, вы должны сначала перенести их во временную таблицу, а после воссоздания таблицы вы должны отодвинуть их обратно. Иногда вы делаете изменения в ограничениях, которые могут потребовать временного отключения ограничений и т. Д. Есть веская причина, почему инструменты, которые делают это на уровне SQL (сравнение двух баз данных), вероятно, все коммерческие.

Даже команда ADO.NET не реализовала это и не будет внедрять это в будущем. Вместо этого они работают над тем, что называется миграцией.

Edit:

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

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

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

2 голосов
/ 25 августа 2011

Лучший способ достичь этого, вероятно, с помощью миграций:

http://nuget.org/List/Packages/EntityFramework.SqlMigrations

Хорошие сообщения в блоге здесь и здесь .

2 голосов
/ 17 июля 2011

Вам необходимо реализовать интерфейс IDatabaseInitializer .

Например

public class MyInitializer : IDatabaseInitializer<MyDbContext>
{
    public void InitializeDatabase(MyDbContext context)
    {
        //your logic here
    }
}

А затем установите инициализатор при запуске приложения

Database.SetInitializer<ProductCatalog>(new MyInitializer());

Вот пример

Вам придется вручную выполнять команды для изменения базы данных.

context.ObjectContext.ExecuteStoreCommand("ALTER TABLE dbo.MyTable ADD NewColumn VARCHAR(20) NULL");

Вы можете использовать такой инструмент, как SQL Compare для изменения сценария.

...