如何在EF代码中首先创建持久计算列?

spr*_*t12 9 sql-server entity-framework code-first ef-migrations

如何使此列与数据库中的PERSISTED COMPUTED列类似?

我当前的尝试(它在种子中加载所有带有null的CompCol行):

    public class Call
    {
        public Call()
        {
        }

        [Key]
        public int Id { get; set; }

        [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
        public string CompCol
        {
            get
            {
                return "ABC-" + Convert.ToString(Id).PadLeft(5, '0');
            }
            protected set {}
        }
}
Run Code Online (Sandbox Code Playgroud)

spr*_*t12 9

我找到的解决方案是:

  1. 确保已关闭自动迁移.这样VS就会生成一个脚本(流畅的api代码)供我们进一步定制而不是仅仅运行它.所以在配置类中:

    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将字段添加到类并将其设置为计算如此,setter是私有的,因为我们显然无法写入计算字段:

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public string BreakdownNo { get; private set; }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后add-migration [xyz-name]在程序包管理器控制台中执行以生成迁移代码,该代码将显示在具有给定名称的迁移文件夹下.

  4. 在迁移内部注释掉代码Up()并添加自定义SQL,如下所示:

    public override void Up()
    {
        //AddColumn("dbo.Calls", "BreakdownNo", c => c.String());
        Sql("ALTER TABLE dbo.Calls ADD BreakdownNo AS ('BD'+RIGHT('00000'+ CAST(Id AS VARCHAR), 6))");
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 做一个update-database在PM和应适当添加计算列.

进一步说明:如果你的公式错误,那么你将不得不通过做一个update-database -targetMigration: [name of migration to go back to]然后做另一个add-migration name并在那里修改你的公式来恢复迁移,最后使用update-database.可能有更好的方法,但这是我发现和使用的方式.

然而,我没有找到使该领域持续存在的方法.

  • 这是一个很好的例子,说明让自动迁移工作得很好是多么困难. (5认同)