【问题标题】:Including sql files when generating Migrations in EF Core - asp.net在 EF Core 中生成迁移时包含 sql 文件 - asp.net
【发布时间】:2019-10-17 00:01:47
【问题描述】:

我们目前正在进行一个项目,它使用 EF 命令自动生成迁移脚本,即 dotnet ef migrations add InitialCreate

除了自动创建的实体,我们还需要从文件中运行sql命令来生成存储过程,这是外部服务所需要的。

手动将以下内容添加到迁移中非常简单,并且可以在本地工作:

var sqlFiles =
    Directory.GetFiles(
        $"{AppDomain.CurrentDomain.BaseDirectory}/sql", "*.sql");
foreach (var sqlFile in sqlFiles)
{
    migrationBuilder.Sql(File.ReadAllText(sqlFile));
}

但是,每次我们运行迁移构建器时都需要再次添加(这相当频繁,因为经常需要添加新模型等),并且在推送到我们的开发服务器时这不起作用,因为它们会自动运行迁移构建器和数据库更新命令。

有没有办法让 EF 在生成迁移时自动包含 sql 文件?或者一般来说有更好的方法?

【问题讨论】:

  • 您对始终在应用启动时执行脚本感到满意吗?我们对从文件执行 SQL 脚本有非常相似的要求,但我们的应用程序总是循环通过 SQL 文件并在启动时执行它们。脚本总是以 DROP IF EXISTS 开始,然后创建。
  • 这可能行得通,我需要与团队再次确认,但值得一试。
  • 我设法安装了这样的东西,谢谢你的想法!它可以在本地工作,但没有机会针对开发服务器进行测试...
  • 没问题!我在下面包含了我们自己的实现作为答案,以便您了解我们是如何实现它的。

标签: c# sql entity-framework


【解决方案1】:

这是我们在应用启动时执行 SQL 脚本的实现,它可能有用,或者至少可以引导您朝某个方向发展。 这是从program.cs 执行的,作为Main() 方法的一部分:

public static void Main(string[] args)
{
    var host = CreateWebHostBuilder(args).Build();
    ExecuteAzureDatabaseScripts(host);
    host.Run();
}


private static void ExecuteAzureDatabaseScripts(IWebHost host)
{
    var scopeFactory = host.Services.GetService<IServiceScopeFactory>();
    using (var scope = scopeFactory.CreateScope())
    {
        var hostingEnvironment = scope.ServiceProvider.GetService<IHostingEnvironment>();

        if (hostingEnvironment.IsDevelopment()) return;

        var scriptRunner = scope.ServiceProvider.GetService<SqlScriptRunner>();
        var storeContext = scope.ServiceProvider.GetService<IStoreDbContext>();
        scriptRunner.Context = storeContext;
        scriptRunner.Directory = @"SqlScripts\Azure";
        scriptRunner.ExecuteScripts();
    }
}

ScriptRunner类:

public class SqlScriptRunner
{
    private IDbContext _context;
    private readonly IHostingEnvironment _hosting;
    private string _directory;

    public SqlScriptRunner(IHostingEnvironment hosting)
    {
        _hosting = hosting;
    }

    public IDbContext Context
    {
        set => _context = value;
    }

    /// <summary>
    /// Name of the directory containing json seed data e.g. Data\Store
    /// </summary>
    public string Directory
    {
        set => _directory = value;
    }

    public void ExecuteScripts()
    {
        if (_context == null) throw new NullReferenceException("Database context for SqlScriptRunner is null.");
        if (string.IsNullOrEmpty(_directory)) throw new NullReferenceException("SqlScriptRunner directory is null or empty.");

        var directoryInfo = new DirectoryInfo( Path.Combine(_hosting.ContentRootPath, _directory));

        foreach (var file in directoryInfo.GetFiles().OrderBy(f => f.FullName))
        {
            var script = File.ReadAllText(file.FullName);
            _context.Database.ExecuteSqlCommand(script);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 2019-02-07
    • 1970-01-01
    • 2017-05-27
    • 2021-08-09
    • 1970-01-01
    • 2020-04-23
    • 2021-11-23
    相关资源
    最近更新 更多