如何在.NET 6的EF Core Code First迁移Up方法中运行指定目录SQL脚本
在类库迁移中加载并运行对应SQL脚本
一、先搞定SQL脚本的属性配置
每个迁移文件夹里的SQL脚本,在Visual Studio里右键→属性,把复制到输出目录设为「如果较新则复制」。编译后脚本会跟着输出到对应目录,不然程序找不到文件。如果想彻底避免路径问题,也可以把脚本设为嵌入的资源(生成操作选这个),后面会讲这种方式。
二、获取SQL脚本的路径/内容
假设你的迁移类对应1文件夹里的InitSchema.sql,两种常用方式:
方式1:基于程序集输出目录拼路径
// 获取当前迁移类所在程序集的输出目录 var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 按实际文件夹层级拼接,比如你的迁移文件夹在类库根目录的Migrations下,就这么写 var scriptPath = Path.Combine(basePath, "Migrations", "1", "InitSchema.sql"); // 读取脚本内容 var scriptContent = File.ReadAllText(scriptPath);
提示:如果迁移文件夹直接在类库根目录,就去掉"Migrations"这一级,根据自己的项目结构调整。
方式2:用嵌入资源(更稳妥)
把脚本设为嵌入资源后,直接从程序集里读内容,不用管路径:
var assembly = Assembly.GetExecutingAssembly(); // 资源名称格式:[类库命名空间].[文件夹层级].[脚本文件名],比如MyLibrary.Migrations.1.InitSchema.sql var resourceName = "MyLibrary.Migrations.1.InitSchema.sql"; using var stream = assembly.GetManifestResourceStream(resourceName); using var reader = new StreamReader(stream); var scriptContent = reader.ReadToEnd();
如果不确定资源名称,可调用assembly.GetManifestResourceNames()输出所有资源名核对。
三、在Up方法里执行脚本
拿到脚本内容后,用EF Core的Sql或SqlAsync执行就行:
同步执行(Up方法默认同步)
protected override void Up(MigrationBuilder migrationBuilder) { // 先按上面的方法拿到scriptContent var basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var scriptPath = Path.Combine(basePath, "Migrations", "1", "InitSchema.sql"); var scriptContent = File.ReadAllText(scriptPath); // 执行SQL脚本 migrationBuilder.Sql(scriptContent); }
异步执行(用Async迁移的情况)
protected override async Task UpAsync(MigrationBuilder migrationBuilder, CancellationToken cancellationToken = default) { var assembly = Assembly.GetExecutingAssembly(); var resourceName = "MyLibrary.Migrations.1.InitSchema.sql"; using var stream = assembly.GetManifestResourceStream(resourceName); using var reader = new StreamReader(stream); var scriptContent = await reader.ReadToEndAsync(cancellationToken); await migrationBuilder.SqlAsync(scriptContent, cancellationToken: cancellationToken); }
四、额外提示
- 路径拼接一定要用
Path.Combine,避免Windows和Linux的路径分隔符问题。 - 如果一个迁移文件夹下有多个SQL脚本,可以用
Directory.GetFiles遍历所有.sql文件,批量读取执行。
内容的提问来源于stack exchange,提问作者niler
相关产品推荐
相关产品推荐

