使用 Entity Framework 更新单次迁移中的列长度和数据
Use Entity Framework to update column length and data in single migration
我正在使用 Entity Framework 进行代码优先迁移。我需要将 VARCHAR(50)
列的长度增加到 VARCHAR(100)
并通过将字符串加倍来更新该列中的所有记录。所以 "abc" 变成 "abcabc" (除非值会超过三个字符)。
能够在单个代码优先迁移中执行此操作会很好,但我无法使其正常工作。我首先尝试使用此代码:
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
using (TheEntityContext ctx = new TheEntityContext())
{
foreach (Entities.SomeTable st in ctx.SomeTables)
st.SomeField = st.SomeField + st.SomeField;
ctx.SaveChanges();
}
但是我得到了这个错误:
The model backing the 'TheEntityContext' context has changed since
the database was created. Consider using Code First Migrations to
update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
我觉得这很奇怪。也许我不能在代码优先迁移中使用 Entity Framework?所以我尝试了这段代码:
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
string sql = "UPDATE SomeTable SET SomeField = SomeField + '' + SomeField";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
但是我得到了这个错误:
String or binary data would be truncated.
那我虽然是ALTER TABLE
语句让字段在UPDATE
语句运行s之前不再生效?所以我将 UDPDATE
语句更改为 50 个字符的字符串并且它 运行 没问题。 运行 Update-Database -Verbose
也表示它不是 运行 在 UPDATE
语句之前 ALTER TABLE
语句。
那么这是怎么回事?我是否必须在一个迁移中 运行 ALTER TABLE
然后在另一个迁移中更新 table 的代码?
重点是 EF 将迁移作为事务的一部分执行。
你在里面打开了一个新的交易,这不是必须的,只需使用
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
Sql("UPDATE dbo.SomeTable SET SomeField = '' + SomeField + SomeField");
在这种情况下,Sql()
函数将 运行 在相同的事务上下文中,错误不应出现。
编辑:澄清Sql()
函数的事务上下文。
您必须创建一个添加迁移并在 Up 方法中写入:
migrationBuilder.AlterColumn<String>(
name: "SomeFiled",
table: "dbo.SomeTable",
unicode: false,
maxLength: 100
);
migrationBuilder.Sql("UPDATE dbo.SomeTable SET SomeField = '' + SomeField + SomeField");
我正在使用 Entity Framework 进行代码优先迁移。我需要将 VARCHAR(50)
列的长度增加到 VARCHAR(100)
并通过将字符串加倍来更新该列中的所有记录。所以 "abc" 变成 "abcabc" (除非值会超过三个字符)。
能够在单个代码优先迁移中执行此操作会很好,但我无法使其正常工作。我首先尝试使用此代码:
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
using (TheEntityContext ctx = new TheEntityContext())
{
foreach (Entities.SomeTable st in ctx.SomeTables)
st.SomeField = st.SomeField + st.SomeField;
ctx.SaveChanges();
}
但是我得到了这个错误:
The model backing the 'TheEntityContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
我觉得这很奇怪。也许我不能在代码优先迁移中使用 Entity Framework?所以我尝试了这段代码:
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
string sql = "UPDATE SomeTable SET SomeField = SomeField + '' + SomeField";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
但是我得到了这个错误:
String or binary data would be truncated.
那我虽然是ALTER TABLE
语句让字段在UPDATE
语句运行s之前不再生效?所以我将 UDPDATE
语句更改为 50 个字符的字符串并且它 运行 没问题。 运行 Update-Database -Verbose
也表示它不是 运行 在 UPDATE
语句之前 ALTER TABLE
语句。
那么这是怎么回事?我是否必须在一个迁移中 运行 ALTER TABLE
然后在另一个迁移中更新 table 的代码?
重点是 EF 将迁移作为事务的一部分执行。
你在里面打开了一个新的交易,这不是必须的,只需使用
AlterColumn("dbo.SomeTable", "SomeField", c => c.String(maxLength: 100, unicode: false));
Sql("UPDATE dbo.SomeTable SET SomeField = '' + SomeField + SomeField");
在这种情况下,Sql()
函数将 运行 在相同的事务上下文中,错误不应出现。
编辑:澄清Sql()
函数的事务上下文。
您必须创建一个添加迁移并在 Up 方法中写入:
migrationBuilder.AlterColumn<String>(
name: "SomeFiled",
table: "dbo.SomeTable",
unicode: false,
maxLength: 100
);
migrationBuilder.Sql("UPDATE dbo.SomeTable SET SomeField = '' + SomeField + SomeField");