Reputation: 6121
I am changing a column from string to int on one table. The migration got built fine with ef migrations add
but when trying to run update
I was got an error that
Conversion failed when converting the nvarchar value 'MyField' to data type int.
I don't need the data so I figured I could modify the up/down to just drop and re-add the columns instead of an alter. This is the old up/down
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<int>(
name: "MyField",
table: "MyTable",
nullable: false,
oldClrType: typeof(string));
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "MyField",
table: "MyTable",
nullable: false,
oldClrType: typeof(int));
}
I changed that the below
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn("MyField", "MyTable");
migrationBuilder.AddColumn<int>(
name: "MyField",
table: "MyTable",
nullable: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn("MyField", "MyTable");
migrationBuilder.AddColumn<string>(
name: "MyField",
table: "MyTable",
nullable: false);
}
Now when running ef database update
I am getting a new error that would make sense...except I cannot find an ALTER TABLE anywhere!
ALTER TABLE only allows columns to be added that can contain nulls, or have a DEFAULT definition specified, or the column being added is an identity or timestamp column, or alternatively if none of the previous conditions are satisfied the table must be empty to allow addition of this column. Column 'PlanType' cannot be added to non-empty table 'Subscriptions' because it does not satisfy these conditions.
What could I be missing that's not allowing me to do this?
** Resolved
Per @strickt01 answer I just had to allow nullable from Down and supply a default value in Up
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn("MyField", "MyTable");
migrationBuilder.AddColumn<int>(
name: "MyField",
table: "MyTable",
defaultValue: 1,
nullable: false);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn("MyField", "MyTable");
migrationBuilder.AddColumn<string>(
name: "MyField",
table: "MyTable");
}
Upvotes: 2
Views: 4668
Reputation: 4048
Dropping the column and then re-creating it does not clear out the data in the table. Your Subscriptions
table will still have rows. Thus when you try to add the column which you declare as non-nullable with no default value you get the error (SQL cannot populate the current rows with non-null values without a default). The ALTER TABLE
statement is referenced because that is the SQL for adding a column:
ALTER TABLE Subscription ADD PlanType int not null
See docs
You will either need to declare a default or create it as non-nullable, populate it as part of the migration and then change it to non-nullable.
Upvotes: 3