Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c# - Default value for Required fields in Entity Framework migrations?

I've added the [Required] data annotation to one of my models in an ASP.NET MVC application. After creating a migration, running the Update-Database command results in the following error:

Cannot insert the value NULL into column 'Director', table 'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies'; column does not allow nulls. UPDATE fails. The statement has been terminated.

This is due to some records having NULL in their Director columns. How can I automatically change those values to some default (say "John Doe") director?

Here is my model:

  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; }
    }

and here is my latest migration:

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());
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In addition to the answer from @webdeveloper and @Pushpendra, you need to manually add updates to your migration to update existing rows. For example:

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"));
}

This is because AlterColumn produces DDL to set the default of the column to some specific value in the table specification. The DDL does not affect existing rows in the database.

You're actually making two changes at the same time (setting the default and making the column NOT NULL) and each of them is valid individually, but since you're making the two at the same time, you can expect the system to 'intelligently' realize your intent and set all NULL values to the default value, but this is not what's expected all the time.

Suppose you're only setting the default value for the column, and not making it NOT NULL. You obviously don't expect all the NULL records to be updated with the default you provide.

So, in my opinion, this is not a bug, and I don't want EF to update my data in the ways that I don't explicitly tell it to do. The developer is responsible to instruct the system about what to do with the data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...