And*_*yuk 87 c# asp.net-mvc entity-framework ef-code-first
我已经将[Required]
数据注释添加到ASP.NET MVC应用程序中的一个模型中.创建迁移后,运行该Update-Database
命令会导致以下错误:
无法将值NULL插入列'Director',表'MOVIES_cf7bad808fa94f89afa2e5dae1161e78.dbo.Movies'; 列不允许空值.更新失败.该语句已终止.
这是因为某些记录的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; }
}
Run Code Online (Sandbox Code Playgroud)
这是我最近的迁移:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Ira*_*chi 105
除了@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"));
}
Run Code Online (Sandbox Code Playgroud)
这是因为AlterColumn
生成DDL以将列的默认值设置为表规范中的某个特定值.DDL不会影响数据库中的现有行.
你实际上是在同一时间进行两次更改(设置默认值并使列为NOT NULL),并且每个更改都是单独有效的,但由于你是同时制作两个,所以你可以期望系统'智能地'实现你的意图并将所有NULL
值设置为默认值,但这不是所期望的.
假设您只设置列的默认值,而不是使其为NOT NULL.您显然不希望使用您提供的默认值更新所有NULL记录.
因此,在我看来,这不是一个错误,我不希望EF以我没有明确告诉它的方式更新我的数据.开发人员负责指示系统如何处理数据.
web*_*per 71
如果我没记错的话,这样的事情应该有效:
AlterColumn("dbo.Movies", "Director", c => c.String(nullable: false, defaultValueSql: "John Doe"));
Run Code Online (Sandbox Code Playgroud)
小智 9
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Since EF Core 2.1, you can use MigrationBuilder.UpdateData
to change values before altering the column (cleaner than using raw SQL):
protected override void Up(MigrationBuilder migrationBuilder)
{
// Change existing NULL values to NOT NULL values
migrationBuilder.UpdateData(
table: tableName,
column: columnName,
value: valueInsteadOfNull,
keyColumn: columnName,
keyValue: null);
// Change column type to NOT NULL
migrationBuilder.AlterColumn<ColumnType>(
table: tableName,
name: columnName,
nullable: false,
oldClrType: typeof(ColumnType),
oldNullable: true);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
70661 次 |
最近记录: |