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

Man*_*ngh 44 c# sql-server asp.net-mvc entity-framework asp.net-mvc-4

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

我是新手代码,如果我想在迁移的update-database命令之前将我的更改保存到SQL脚本文件,是否可能?

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

Rik*_*ard 72

首先,您需要创建迁移.

Add-Migration RunSqlScript
Run Code Online (Sandbox Code Playgroud)

然后在生成的迁移文件中,您可以编写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));
Run Code Online (Sandbox Code Playgroud)

然后你跑

Update-Database
Run Code Online (Sandbox Code Playgroud)

  • 您将SQL文件放在项目中的哪个位置,以便在运行时获取它们?`Path.Combine(AppDomain.CurrentDomain.BaseDirectory`将我放入调试目录. (5认同)
  • @fikkatra如果为SP文件夹设置"复制到输出目录"为"始终复制",您将在生产中获得.sql脚本.我使用这样的东西:var sqlFilesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.Substring(0,AppDomain.CurrentDomain.BaseDirectory.IndexOf("bin")),"FolderNameWithMySP"); (3认同)
  • 这对我来说就像魔术一样.我进一步研究并发现我们可以使用下面的代码添加预先创建的存储过程.var sqlFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,@"Custom.sql"); SQL(File.ReadAllText(SQLFILE)); (2认同)
  • Reuel Ramos Ribeiro,不好主意. (2认同)

Yan*_*lla 29

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

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

  1. 在Visual Studio中一定要设置为启动项目中,你的项目DbContext定义
  2. 在Visual Studio中打开PMC:查看 - >其他Windows - >程序包管理器控制台
  3. 在PMC中将默认项目设置为包含DbContext的项目
  4. 如果您同时安装了EF核心和EF 6.x:

    EntityFramework\Add-Migration RunSqlScript

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

    Add-Migration RunSqlScript

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

解决方案资源管理器中的迁移文

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

RunSqlScript迁移中更新Up方法

public override void Up()
{
    string sqlResName = typeof(RunSqlScript).Namespace  + ".201801310940543_RunSqlScript.sql";
    this.SqlResource(sqlResName );
}
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助

  • 我喜欢这种方法。注意:如果这样做,请勿尝试将.sql嵌套在迁移文件下...这会破坏资源的嵌入。请勿套用。 (2认同)
  • 很不错。只是想补充一点,如果您的迁移后 sql 脚本位于同一程序集的不同文件夹中,您可以像这样检索它: `var resourceNames = this.GetType().Assembly.GetManifestResourceNames(); var sqlResourceName = resourceNames.SingleOrDefault(r => r.Contains("201801310940543_RunSqlScript.sql"));` (2认同)

mon*_*van 7

像SQL一样,我们有另一种方法SqlFile.你可以直接使用它.


Mon*_*hus 7

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

protected override void Up(MigrationBuilder migrationBuilder)
{
   var schema = "starter_core";
   migrationBuilder.Sql($"INSERT INTO [{schema}].[Roles] ([Name]) VALUES ('transporter')");
}
Run Code Online (Sandbox Code Playgroud)