Пользовательская стратегия инициализации для кода EF Сначала, которая не отбрасывает таблицы, чтобы добавить столбец

StackOverflow https://stackoverflow.com/questions/5312017

Вопрос

Последний пакет EF Code First Nuget поставляется с пользовательской реализацией IDatabaseInitializer называется DontDropDbJustCreateTablesIfModelChanged. Анкет Как следует из названия, когда будет обнаружено изменение модели, оно не будет отбросить и воссоздать всю базу данных, просто бросьте и воссоздайте таблицы.

Скажи, что у меня есть этот модельный класс:

public class User
{
    public string Username { get; set; }

    // This property is new; the model has changed!
    public string OpenID { get; set; }
}

Как можно было бы внедрить IDatabaseInitializer что тоже не бросает столов. Анкет В этом случае это просто добавило бы OpenID столбец для пользователя таблица?

Это было полезно?

Решение

Я думаю, что это вопрос SQL. Итак, для SQL Server вы можете написать что -то вроде:

public class MyInitializer : IDatabaseInitializer<MyContext>
{
    public void InitializeDatabase(MyContext context)
    {
        context.Database.SqlCommand(
            @"
            IF NOT EXISTS (SELECT 1 FROM sys.columns AS col
                           INNER JOIN sys.tables AS tab ON tab.object_Id = col.object_Id
                           WHERE tab.Name = 'User' AND col.Name = 'OpenId')
            BEGIN
                ALTER TABLE dbo.User ADD OpenId INT; 
            END");
    }
}

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

Другие советы

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

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
    protected override void Seed(MyContext context)
    {
        var countries = new List<Country>
        {
            new Country {Id=1, Name="United Kingdom"},
            new Country{Id=2, Name="Ireland"}
        };

        countries.ForEach(c => context.Countries.Add(c));
    }
}

А затем используйте это в своем Application_Start:

Database.SetInitializer<MyContext>(new MyDbInitializer());

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top