【问题标题】:Create table and insert data into it during EF code first migration在 EF 代码首次迁移期间创建表并将数据插入其中
【发布时间】:2022-04-12 18:27:42
【问题描述】:

我将实体框架代码优先与代码优先迁移一起使用。

在迁移过程中,我需要创建一个新表,然后向其中插入一些数据。

所以我创建了表格:

CreateTable("MySchema.MyNewTable",
    c => new
    {
        MYCOLUMNID = c.Int(nullable: false, identity: true),
        MYCOLUMNNAME = c.String(),
     })
   .PrimaryKey(t => t.MYCOLUMNID);

然后我尝试插入数据:

using (var context = new MyContext())
{
    context.MyNewTableDbSet.AddOrUpdate(new[]
    {
    new MyNewTable
    {
       MYCOLUMNNAME = "Test"
    }
    });
    context.SaveChanges();
}

但我得到一个错误:

无效的对象名称“mySchema.MyNewTable”。

有可能做我需要的吗?在同一迁移中创建一个表并将数据插入其中?

我已经进行了其他迁移,我在其中创建表或将数据插入到表中,但从未在同一个迁移中...

【问题讨论】:

    标签: c# entity-framework entity-framework-6 entity-framework-migrations


    【解决方案1】:

    我的建议是将插入代码移至Seed 方法。 Migrations 在 DbMigrationsConfiguration 类上引入了自己的 Seed 方法。这个Seed 方法与数据库初始化器Seed 方法在两个重要方面不同:

    • 只要执行Update-Database PowerShell 命令,它就会运行。 除非正在使用 Migrations 初始化程序,否则 Migrations Seed 应用程序启动时不会执行该方法。
    • 它必须处理数据库已经包含数据的情况,因为 迁移正在发展数据库,而不是放弃和 重新创建它。

    出于最后一个原因,在Seed 方法中使用AddOrUpdate 扩展方法很有用。 AddOrUpdate 可以检查数据库中是否已经存在实体,然后如果不存在则插入新实体,如果存在则更新现有实体。

    所以,尝试以这种方式运行您想要的脚本:

     Update-Database –TargetMigration: ScriptName 
    

    Seed 方法将完成插入数据的工作。

    正如朱莉·勒曼在她的blog 上所说的:

    AddOrUpdate 的工作是确保您不会创建重复项 当您在开发过程中播种数据时。

    【讨论】:

      【解决方案2】:

      您可以尝试这种方法: 创建表后, 使用以下命令在您的包管理器控制台中创建另一个空迁移:

      Add-Migration "MigrationName"
      

      然后打开该迁移的.cs 文件,并在Up() 方法中插入以下代码:

      Sql("INSERT INTO MyNewTable(NyColumnName) Values('Test')");
      

      之后,保存并返回包管理器控制台并使用以下命令更新数据库:

      Update-Database
      

      【讨论】:

      • 如果我把它放在 Up 方法中,我得到 Sql 在当前上下文中不存在。无法解析符号 Sql。你能提供一个更完整的例子来说明你将如何使用它吗?
      • @egmfrs 你在使用 EntityFrameworkCore 吗?这个问题涉及 EntityFramework6。在 EntityFrameworkCore 中,您将使用 migrationBuilder.Sql()(其中 migrationBuilder 是您的 Up() 方法的第一个参数的名称)而不是 this.Sql()
      • @binki 谢谢,你是对的 - 这确实有效。我正在使用 EF 核心,并且在我的项目中成功地使用了已接受的答案和您的建议。
      【解决方案3】:

      在迁移中做“随机”事情的一种方法是使用Sql method 并传递您需要执行的任何 SQL 语句,例如插入数据。

      如果您希望您的迁移能够生成完整的迁移 SQL 脚本,包括您的数据操作,这是最好的方法(Seed 方法只能在代码中执行,不会生成任何 sql 脚本)。

      【讨论】:

        【解决方案4】:

        对于那些正在寻找EF Core 解决方案的人,在Up 方法中,并在创建表之后:

        即:migrationBuilder.CreateTable(name: "MyTable", .....

        添加以下代码:

        migrationBuilder.InsertData(table: "MyTable", column: "MyColumn", value: "MyValue");

        migrationBuilder.InsertData(table: "MyTable", columns: ..., values: ...);

        有关更多信息,请参阅文档:MigrationBuilder.InsertData Method

        【讨论】:

          【解决方案5】:

          首先我运行

          PM> Add-Migration MyTableInsertInto

          然后我得到了关注,

          **此迁移文件的设计器代码包含您当前 Code First 模型的快照。此快照用于在您构建下一次迁移时计算对模型的更改。如果您对要包含在此迁移中的模型进行其他更改,则可以通过再次运行“Add-Migration MyTableInsertInto”来重新构建它。 ** 我使用以下代码进行 c# 数据迁移

          public partial class MyTableInsertInto : DbMigration
              {
                  public override void Up()
                  {
                      Sql("INSERT INTO MyNewTable(MyColumnName) Values ('Test')");
                  }
                  
                  public override void Down()
                  {
                      Sql("DELETE MyNewTable WHERE MyColumnName= 'Test'");
                  }
              }
          

          然后我运行以下

          PM> 更新数据库

          指定“-Verbose”标志以查看应用于目标数据库的 SQL 语句。 应用显式迁移:[202204120936266_MyNewTableInsertInto]。 应用显式迁移:202204120936266_MyNewTableInsertInto。 运行种子方法。

          运行种子方法数据库成功更新后,这对我来说很好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-18
            • 2021-04-22
            • 2018-05-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多