我们可以使用代码优先迁移运行 SQL 脚本吗?

Posted

技术标签:

【中文标题】我们可以使用代码优先迁移运行 SQL 脚本吗?【英文标题】:Can we run SQL script using code first migrations? 【发布时间】:2015-11-14 13:11:27 【问题描述】:

我们可以使用代码优先迁移运行 sql 脚本吗?

我是第一次编码的新手,如果我想在迁移的 update-database 命令之前将我的更改保存到 SQL 脚本文件,可以吗?

如果可能,请提供完成它的步骤。此外,如果生成了脚本,那么我是否可以使用迁移来运行该脚本?

【问题讨论】:

【参考方案1】:

首先您需要创建一个迁移。

Add-Migration RunSqlScript

然后在生成的迁移文件中你可以编写你的 SQL。

// PLAIN SQL
Sql("UPDATE dbo.Table SET Created = GETDATE()");

// FROM FILE
var sqlFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Custom.sql"); 
Sql(File.ReadAllText(sqlFile));

然后你运行

Update-Database

【讨论】:

这对我来说就像魔术一样。我进一步研究发现我们可以使用下面的代码添加预先创建的存储过程。 var sqlFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Custom.sql"); Sql(File.ReadAllText(sqlFile)); 您将 SQL 文件放在项目中的什么位置,以便在运行时获取它们? Path.Combine(AppDomain.CurrentDomain.BaseDirectory 让我进入调试目录。 鲁埃尔·拉莫斯·里贝罗,坏主意。 @Kate 你能详细说明为什么这是一个坏主意,更重要的是,应该如何正确地完成它? @fikkatra 如果您将带有 SP 的文件夹的“复制到输出目录”设置为“始终复制”,您将在生产中获得 .sql 脚本。我使用这样的东西:var sqlFilesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.Substring(0, AppDomain.CurrentDomain.BaseDirectory.IndexOf("bin")), "FolderNameWithMySP");【参考方案2】:

我喜欢做的是将 SQL 脚本作为资源嵌入到程序集中并使用SqlResource 方法。我已经使用 Visual Studio 2017 15.5.6 测试了这种方法。

首先你需要创建一个迁移文件:

    在 Visual Studio 中,确保将定义 DbContext 的项目设置为启动项目 在 Visual Studio 中打开 PMC:查看 -> 其他窗口 -> 包管理器控制台 在 PMC 中将默认项目设置为保存 DbContext 的项目

    如果您同时安装了 EF 核心和 EF 6.x:

    EntityFramework\Add-Migration RunSqlScript

    如果您只安装了 EF 6.x:

    Add-Migration RunSqlScript

在迁移文件夹中添加一个Sql Script(我用与迁移文件相同的前缀命名)

在文件属性窗口中确保构建操作是“嵌入式资源” 请注意,我们不需要复制到输出文件夹,因为 sql 脚本将嵌入到程序集中。

更新RunSqlScript迁移中的Up方法

public override void Up()

    string sqlResName = typeof(RunSqlScript).Namespace  + ".201801310940543_RunSqlScript.sql";
    this.SqlResource(sqlResName );

希望对你有帮助

【讨论】:

我喜欢这种方法。注意:如果这样做,请不要尝试将.sql 嵌套在迁移文件下...这会破坏资源的嵌入。让它不嵌套。 非常好。只想补充一点,如果您的迁移后 sql 脚本位于同一程序集的不同文件夹中,您可以像这样检索它:var resourceNames = this.GetType().Assembly.GetManifestResourceNames(); var sqlResourceName = resourceNames.SingleOrDefault(r => r.Contains("201801310940543_RunSqlScript.sql")); @KrisColeman,你说“这破坏了资源的嵌入”是什么意思。我没有看到任何关于嵌套 .sql 文件的问题。 对不起,应该是“嵌入资源”当我尝试将文件与迁移文件嵌套时,它在运行时找不到资源。 我玩过@Rikard 的答案,结果和这个差不多,效果很好。我已经使用Sql(File.ReadAllText(sqlFile)); 将生成的 Up() 和 Down() 迁移方法与一些各自的自定义 SQL MyMigrationNameUp/Down.sql 脚本相结合 - 效果很好!!【参考方案3】:

和 SQL 一样,我们还有另一个方法 SqlFile。你可以直接使用它。

【讨论】:

你有例子吗? 在 Generated Migration.cs 中写入以下行SqlFile("Custom.sql") Ref - [msdn] : msdn.microsoft.com/en-us/library/dn857435(v=vs.113).aspx 【参考方案4】:

对于 .NET Core 和 EF Core,您可以在迁移中执行类似的操作

protected override void Up(MigrationBuilder migrationBuilder)

   var schema = "starter_core";
   migrationBuilder.Sql($"INSERT INTO [schema].[Roles] ([Name]) VALUES ('transporter')");

【讨论】:

以上是关于我们可以使用代码优先迁移运行 SQL 脚本吗?的主要内容,如果未能解决你的问题,请参考以下文章

MitratorDotNet (Migrator.Net) - 我可以只使用裸 SQL 上/下迁移文件吗?

在生产中使用实体框架(代码优先)迁移

使用 Flyway 在多个模式上运行 SQL 脚本

我可以将依赖项注入迁移(使用 EF-Core 代码优先迁移)吗?

骑士。 EF 代码优先迁移

我可以在不重新运行迁移的情况下修复 Flyway 中的版本号吗?