Пользовательская стратегия инициализации для кода EF Сначала, которая не отбрасывает таблицы, чтобы добавить столбец
-
24-10-2019 - |
Вопрос
Последний пакет 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, но не было готово к выпуску в то время, когда вышел код первого капли. Вы можете увидеть предварительный просмотр здесь: Код первых миграций