entity framework迁移中必填字段的默认值?
我在ASP.NET MVC应用程序中添加了[Required]
数据注释。 创build迁移后,运行update-database
resuilts,出现以下错误:
无法将值NULL插入到'Director'列中,'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies'; 列不允许空值。 更新失败。 该语句已终止。
这是由于一些logging在其Director
列中有NULL。 我该如何自动将这些值改变为默认值(如“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()); } }
如果我没有记错的话,应该这样做:
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),并且每个都是单独有效的,但是由于你同时做了这两个,你可以期望系统'智能地“实现你的意图,并将所有的NULL
值设置为默认值,但这不是所有的预期。
假设你只是设置列的默认值,而不是使它不为NULL。 你显然不希望所有的NULLlogging都用你提供的默认值进行更新。
所以,在我看来,这不是一个错误,我不希望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"
时,我得到了一个错误,然后我意识到他们正在期待一个像"GETDATE()"
的SQL值,所以我尝试了"'NY'"
,并做了这个把戏
整条线看起来像这样
AddColumn("TABLE_NAME", "State", c => c.String(maxLength: 2, nullable: false, defaultValueSql: "'NY'"));
感谢这个答案 ,让我走上正轨
我发现只要在实体属性上使用Auto-Property Initializer就足以完成工作。
例如:
public class Thing { public bool IsBigThing { get; set; } = false; }