entity-framework - 代码优先 EF6 SqlServerMigrationSqlGenerator 中的自定义逻辑不起作用

标签 entity-framework sql-server-2012 ef-code-first

我正在尝试通过 SqlServerMigrationSqlGenerator 类在代码优先的 Entity Framework 6 迁移中为表“dbo.Table1”中名为“Duration”的计算列设置默认值 SQL。

我尝试在 AddColumnOperation 和 CreateTableOperation 的生成方法中设置此项。虽然 Generate method for column 下的代码永远不会触发,但 Generate table 下的代码会触发并抛出错误,说明如下。 (EndTime 列是表 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 - 代码优先 EF6 SqlServerMigrationSqlGenerator 中的自定义逻辑不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29702731/

相关文章:

sql-order-by - T-SQL 为什么除以零不会在 order by 子句中产生错误

.net - EF 迁移 resx 文件中的目标字段采用哪种格式?

c# - EntityFramework 6 现有数据库和新数据库的迁移?

c# - 将导航属性设置为 null 不会保存到数据库

SQL Server 滚动排名

sql-server - 使用生成脚本从sql server 2012导出日期数据

c# - Entity Framework 7 无法创建迁移,因为存在同名的导航属性

entity-framework - 在代码优先 Entity Framework 中手动编辑数据库

entity-framework - 如何将我自己的约定添加到 EF 4.3(使列大写)

entity-framework - Entity Framework : "Store update, insert, or delete statement affected an unexpected number of rows (0)."