简体   繁体   English

EF迁移,从外部文件读取和执行SQL,引用问题

[英]EF migration, reading and executing SQL from external file, quote problem

I wanted to use Entity Framework migrations in my .NET 6 application for creating and altering views.我想在我的 .NET 6 应用程序中使用实体框架迁移来创建和更改视图。 I found a relevant article covering this for stored procedures at https://do.netthoughts.net/creating-stored-procs-in-efcore-migrations/ .我在https://do.netthoughts.net/creating-stored-procs-in-efcore-migrations/找到了一篇涵盖此存储过程的相关文章。 Following the approach there (except for the EmbeddedResource part, I'm not sure what that's for), for testing purposes I've created two scripts.按照那里的方法(除了 EmbeddedResource 部分,我不确定那是什么),出于测试目的,我创建了两个脚本。 One, x1.sql, creates a view and the other, x0.sql, drops it.一个 x1.sql 创建一个视图,另一个 x0.sql 删除它。 These files are in a scripts subfolder of the Migrations folder where all the migration class files are stored.这些文件位于所有迁移 class 文件存储的Migrations文件夹的scripts子文件夹中。

x1.sql x1.sql

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE VIEW [dbo].XYZ AS 
SELECT Panels.PanelId, Panels.Name
FROM Panels

GO

x0.sql x0.sql

DROP VIEW IF EXISTS [dbo].[XYZ]
GO

For the migration file, with no database changes having been made since the last database update, I added a migration, do.net ef migrations add CreateXyzView .对于迁移文件,自上次数据库更新以来没有对数据库进行任何更改,我添加了一个迁移, do.net ef migrations add CreateXyzView I edited the resulting migration file to read as follows:我编辑了生成的迁移文件,内容如下:

using System.Reflection;

using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MyProject.Migrations
{
    public partial class CreateXyzView : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            using StreamReader reader = new StreamReader("Migrations/scripts/x1.sql");
            var sqlScript = reader.ReadToEnd();
            migrationBuilder.Sql($"EXEC(N'{sqlScript}')");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            using StreamReader reader = new StreamReader("Migrations/scripts/x0.sql");
            var sqlScript = reader.ReadToEnd();
            migrationBuilder.Sql($"EXEC(N'{sqlScript}')");
        }
    }
}

Now, when I run do.net ef database update , I'm getting an error:现在,当我运行do.net ef database update时,出现错误:

Error Number:105,State:1,Class:15
Unclosed quotation mark after the character string 'SET ANSI_NULLS ON
'.
Incorrect syntax near 'SET ANSI_NULLS ON
'.

Since it's repeating the first line of each of my SQL scripts, this tells me at least that it's reading one of them, presumably x1.sql, but it isn't dealing with the content successfully as I'd expected it to based on the source article.由于它重复我的每个 SQL 脚本的第一行,这至少告诉我它正在读取其中一个,大概是 x1.sql,但它没有像我预期的那样成功处理内容基于来源文章。 Any ideas what's wrong here, whether this can be fixed?任何想法这里出了什么问题,这是否可以解决? There aren't even any quotes in my scripts, so that can't be what's throwing things off!我的脚本中甚至没有任何引号,所以这不可能是什么东西丢掉了!

Try something like this.尝试这样的事情。

protected override void Up(MigrationBuilder migrationBuilder)
{
    // use the correct path to file here
    var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, baseFolder, subFolder, fileName); 

    if (File.Exists(path))
    {
        migrationBuilder.Sql(File.ReadAllText(path));
    }
}

And set the following properties for the sql file并为 sql 文件设置以下属性

Build action : Embedded resource构建操作Embedded resource

Copy to Output Directory : Copy if newer复制到 Output 目录Copy if newer

SQL Server Utilities Statements - GO . SQL 服务器实用程序报表 - GO GO is not a Transact-SQL statement. GO 不是 Transact-SQL 语句。 You should not use it in your SQL.你不应该在你的 SQL 中使用它。

The CREATE VIEW must be the first statement in a query batch. CREATE VIEW必须是查询批处理中的第一条语句。 Therefore, you will have to split your SQL into several parts and execute each of them separately.因此,您必须将 SQL 分成几个部分并分别执行每个部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM