Значение по умолчанию для обязательных полей в миграции 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());
}
}
778   6  

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

    Ничего не найдено.