代码优先 EF6 SqlServerMigrationSqlGenerator 中的自定义逻辑不起作用
Custom logic in code-first EF6 SqlServerMigrationSqlGenerator not working
我正在尝试在代码优先 Entity Framework 中为 table 'dbo.Table1' 中名为 'Duration' 的计算列设置默认值 SQL 6 通过 SqlServerMigrationSqlGenerator 迁移 class.
我尝试在 AddColumnOperation 和 CreateTableOperation 的生成方法中进行设置。虽然 Generate method for column 下的代码永远不会触发,但 Generate table 下的代码会触发并抛出错误,说明以下内容。 (EndTime 列是 table dbo.Table1 中的一列,StartTime 也是如此)
The name "EndTime" is not permitted in this context. Valid expressions
are constants, constant expressions, and (in some contexts) variables.
Column names are not permitted.
问题:我怎样才能在下面代码中的任一生成方法中完成这项工作?
internal class CustomImplForSqlServerMigration: SqlServerMigrationSqlGenerator {
protected override void Generate(AlterColumnOperation alterColumnOperation) {
base.Generate(alterColumnOperation);
}
protected override void Generate(AddColumnOperation addColumnOperation) {
if (addColumnOperation.Table == "dbo.Table1" && addColumnOperation.Column.Name == "Duration") {
addColumnOperation.Column.DefaultValueSql = "(CAST(CAST(EndTime AS DATETIME) - CAST(StartTime AS DATETIME) AS TIME))";
}
base.Generate(addColumnOperation);
}
protected override void Generate(CreateTableOperation createTableOperation) {
if (createTableOperation.Name == "dbo.Table1") {
foreach(ColumnModel cm in createTableOperation.Columns) {
if (cm.Name == "Duration") {
cm.DefaultValueSql = "(CAST(CAST(EndTime AS DATETIME) - CAST(StartTime AS DATETIME) AS TIME))";
}
}
}
base.Generate(createTableOperation);
}
}
更新 1:
我使用另一种简单的方法来添加自定义逻辑,以便使用 ExecuteSqlCommand 修改数据库对象。只需按照以下步骤在您的情况下使用它。
- 想出用于修改或创建数据库对象的自定义脚本
- 在 Seed 方法中为每个自定义脚本执行一个命令
确保将 ExecuteSqlCommand 语句放在 Seed 方法的末尾,并且在自定义脚本代码之前调用 context.SaveChanges( ) 方法,以防对种子数据有依赖性
protected override void Seed(EfCodeFirst.ShiftsDb context)
{
//Write your seed data statements
//call SaveChanges in case your custom script depends
//on some seed data
context.SaveChanges();
//include your custom scripts like ALTER TABLE
//or CREATE PROCEDURE or anything else
//use a ExecuteSqlCommand for every custom script
context.Database.ExecuteSqlCommand(@"ALTER TABLE ShiftTypes DROP COLUMN Duration;
ALTER TABLE TABLE1 ADD Duration AS (CAST(CAST(EndTime AS DATETIME) -
CAST(StartTime AS DATETIME) AS TIME)); ");
}
这不是 EF 的限制,而是数据库本身的限制 - 您不能引用默认值规范中的其他列。相反,我建议您编写用于插入新 Table1 实体的存储过程,然后根据 article.
使用流畅的 api 进行映射
我正在尝试在代码优先 Entity Framework 中为 table 'dbo.Table1' 中名为 'Duration' 的计算列设置默认值 SQL 6 通过 SqlServerMigrationSqlGenerator 迁移 class.
我尝试在 AddColumnOperation 和 CreateTableOperation 的生成方法中进行设置。虽然 Generate method for column 下的代码永远不会触发,但 Generate table 下的代码会触发并抛出错误,说明以下内容。 (EndTime 列是 table dbo.Table1 中的一列,StartTime 也是如此)
The name "EndTime" is not permitted in this context. Valid expressions are constants, constant expressions, and (in some contexts) variables. Column names are not permitted.
问题:我怎样才能在下面代码中的任一生成方法中完成这项工作?
internal class CustomImplForSqlServerMigration: SqlServerMigrationSqlGenerator {
protected override void Generate(AlterColumnOperation alterColumnOperation) {
base.Generate(alterColumnOperation);
}
protected override void Generate(AddColumnOperation addColumnOperation) {
if (addColumnOperation.Table == "dbo.Table1" && addColumnOperation.Column.Name == "Duration") {
addColumnOperation.Column.DefaultValueSql = "(CAST(CAST(EndTime AS DATETIME) - CAST(StartTime AS DATETIME) AS TIME))";
}
base.Generate(addColumnOperation);
}
protected override void Generate(CreateTableOperation createTableOperation) {
if (createTableOperation.Name == "dbo.Table1") {
foreach(ColumnModel cm in createTableOperation.Columns) {
if (cm.Name == "Duration") {
cm.DefaultValueSql = "(CAST(CAST(EndTime AS DATETIME) - CAST(StartTime AS DATETIME) AS TIME))";
}
}
}
base.Generate(createTableOperation);
}
}
更新 1:
我使用另一种简单的方法来添加自定义逻辑,以便使用 ExecuteSqlCommand 修改数据库对象。只需按照以下步骤在您的情况下使用它。
- 想出用于修改或创建数据库对象的自定义脚本
- 在 Seed 方法中为每个自定义脚本执行一个命令
确保将 ExecuteSqlCommand 语句放在 Seed 方法的末尾,并且在自定义脚本代码之前调用 context.SaveChanges( ) 方法,以防对种子数据有依赖性
protected override void Seed(EfCodeFirst.ShiftsDb context) { //Write your seed data statements //call SaveChanges in case your custom script depends //on some seed data context.SaveChanges(); //include your custom scripts like ALTER TABLE //or CREATE PROCEDURE or anything else //use a ExecuteSqlCommand for every custom script context.Database.ExecuteSqlCommand(@"ALTER TABLE ShiftTypes DROP COLUMN Duration; ALTER TABLE TABLE1 ADD Duration AS (CAST(CAST(EndTime AS DATETIME) - CAST(StartTime AS DATETIME) AS TIME)); "); }
这不是 EF 的限制,而是数据库本身的限制 - 您不能引用默认值规范中的其他列。相反,我建议您编写用于插入新 Table1 实体的存储过程,然后根据 article.
使用流畅的 api 进行映射