Значение по умолчанию для обязательных полей в миграции Entity Framework?
я добавил [Required] аннотация данных к одной из моих моделей в ASP.NET приложение MVC. После создания миграции запустите Update-Database команды приводит к следующей ошибке:
не удается вставить значение NULL в столбец "директор", таблица
'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.ДБО.Фильмы'; колонка не делает
разрешить значения null. Сбой обновления. Заявление было прекращено.
Это связано с тем, что некоторые записи имеют значение NULL в их Director столбцы. Как я могу автоматически изменить эти значения на некоторые значения по умолчанию (скажем, "John Doe") директор?
вот моя модель:
public class Movie
{
public int ID { get; set; }
[Required]
public string Title { get; set; }
[DataType(DataType.Date)]
public DateTime ReleaseDate { get; set; }
[Required]
public string Genre { get; set; }
[Range(1,100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[StringLength(5)]
public string Rating { get; set; }
[Required] /// <--- NEW
public string Director { get; set; }
}
и вот моя последняя миграция:
public partial class AddDataAnnotationsMig : DbMigration
{
public override void Up()
{
AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false));
AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false));
AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5));
AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false));
}
public override void Down()
{
AlterColumn("dbo.Movies", "Director", c => c.String());
AlterColumn("dbo.Movies", "Rating", c => c.String());
AlterColumn("dbo.Movies", "Genre", c => c.String());
AlterColumn("dbo.Movies", "Title", c => c.String());
}
}
6 ответов:
Если я правильно помню, что-то вроде этого должно работать:
AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false, defaultValueSql: "John Doe"));
В дополнение к ответу от @webdeveloper и @Pushpendra, вам нужно вручную добавить обновления в вашу миграцию, чтобы обновить существующие строки. Например:
public override void Up() { Sql("UPDATE [dbo].[Movies] SET Title = 'No Title' WHERE Title IS NULL"); AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); }Это так
AlterColumnпроизводит DDL, чтобы установить значение по умолчанию столбца на некоторое конкретное значение в спецификации таблицы. DDL не влияет на существующие строки в базе данных.вы фактически делаете два изменения одновременно (устанавливая значение по умолчанию и делая столбец не нулевым), и каждый из них они действительны индивидуально, но поскольку вы делаете их одновременно, вы можете ожидать, что система "разумно" реализует ваше намерение и устанавливает все
NULLзначения по умолчанию, но это не то, что ожидалось все время.предположим, что вы только устанавливаете значение по умолчанию для столбца, а не делаете его NOT NULL. Вы, очевидно, не ожидаете, что все нулевые записи будут обновлены с помощью значения по умолчанию, которое вы предоставляете.
Так что, по-моему, это не баг, а я не хочу, чтобы EF обновлял мои данные так, как я явно не говорю ему делать. Разработчик несет ответственность за инструктаж системы о том, что делать с данными.
public partial class AddDataAnnotationsMig : DbMigration { public override void Up() { AlterColumn("dbo.Movies", "Title", c => c.String(nullable: false,defaultValue:"MyTitle")); AlterColumn("dbo.Movies", "Genre", c => c.String(nullable: false,defaultValue:"Genre")); AlterColumn("dbo.Movies", "Rating", c => c.String(maxLength: 5)); AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false,defaultValue:"Director")); } public override void Down() { AlterColumn("dbo.Movies", "Director", c => c.String()); AlterColumn("dbo.Movies", "Rating", c => c.String()); AlterColumn("dbo.Movies", "Genre", c => c.String()); AlterColumn("dbo.Movies", "Title", c => c.String()); } }
не уверен, что этот параметр всегда был рядом, но просто столкнулся с подобной проблемой, обнаружил, что я смог установить значение по умолчанию без запуска каких-либо ручных обновлений, используя следующее
defaultValueSql: "'NY'"я получил ошибку, когда предоставленное значение было
"NY"тогда я понял, что они ожидают значение SQL, как"GETDATE()"Так я пробовал"'NY'"и это сделало трюквся строка выглядит так
AddColumn("TABLE_NAME", "State", c => c.String(maxLength: 2, nullable: false, defaultValueSql: "'NY'"));спасибо ответ, я на правильном пути
Я обнаружил, что просто с помощью инициализатора Auto-Property на entity property достаточно, чтобы выполнить эту работу.
например:
public class Thing { public bool IsBigThing { get; set; } = false; }
по какой-то причине, что я не смог объяснить себя, одобренный ответ больше не работает для меня.
он работал на другом приложении, на том, что я работаю, это не так.
да, альтернатива, но довольно неэффективно, решение было бы переопределить метод SaveChanges (), как показано ниже. Этот метод должен быть в классе контекста.
public override int SaveChanges() { foreach (var entry in ChangeTracker.Entries().Where(entry => entry.Entity.GetType().GetProperty("ColumnName") != null)) { if (entry.State == EntityState.Added) { entry.Property("ColumnName").CurrentValue = "DefaultValue"; } }
Comments