繁体   English   中英

CodeFirst 迁移:如何在自动完成“更新数据库”后运行数据库脚本(C# 或 SQL)?

[英]CodeFirst migrations: How to run a database script (C# or SQL) after completion of “update-database” automatically?

我正在使用 EF.Core 和代码优先迁移来更新 SQL 数据库。

每当我添加迁移(包管理器控制台: add-migration )时,我都会使用众所周知的update-database命令更新数据库。 有没有办法在自动完成此命令后运行 SQL 批处理脚本(就像您可以在 Visual Studio 中处理构建后事件一样)?

该脚本可以备份数据库或执行其他任务(例如设置用户角色等)。

我不想修改现有的迁移来做到这一点,我知道你可以添加类似的东西

   protected override void Up(MigrationBuilder migrationBuilder)
   {
        var sqlFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, 
                       @"Migrations\20200701103006_MySQLBatch_Up.sql");
        var sqlCommands = System.IO.File.ReadAllText(sqlFile);
        migrationBuilder.Sql(sqlCommands);

        // ...
   }

但我不想这样做,因为这样每次添加新迁移时都必须这样做。

是否有可以覆盖的事件或方法来实现它? 或者可以触发的东西,比如脚本?

实际上,我想要实现的是有一个脚本或方法调用:

update-database
pg_dump -h localhost -U postgres -p 5432 myDatabase > C:\Temp\myDatabase.sql

注意: update-database 在 Package 管理器上下文中运行,pg_dump 在命令 shell (cmd.exe) 中运行 - 因此,您不能在 a.ZDFFF0A7FA1A55C6452 或 batDA 脚本中直接运行 update-database。

我似乎无法在文档中找到任何东西来以你想要的方式做你想做的事。

但是,我想到的另一种解决方案是,不是从命令行运行脚本或作为迁移 class 的一部分,而是在启动时运行它们作为自动迁移的一部分。

所以你可以做这样的事情:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
{
    // migrate changes on startup
    dataContext.Database.Migrate();
    foreach(var file in GetMigrationFiles())//you can write the code that searches a folder for SQL scripts to execute
    {       
       dataContext.Database.ExecuteSqlRaw(File.ReadAllText(file));
    }
}

确保正确订购 GetMigrationFiles()。

这里的问题是,如果您想回滚,您还需要编写 SQL 来回滚您的自定义 SQL。 不过,将它们放在不同的文件夹中。

我能想到的两个选择

  1. 更简单:为什么不使用一个简单的批处理文件来依次执行这两个命令,然后您可以运行批处理文件而不是Update-Database命令? 您甚至可以从标准项目配置文件中获取最多的参数,这样您就可以在多个项目中使用相同的脚本,而无需更改项目配置文件之外的任何内容。 这样,您可以确保您的附加脚本在实际预期时响应Update-Database命令运行

  2. If this is for a Powershell session that may involve multiple "update-commands" in a dynamic manner and you don't want the above approach, then you can try subscribing to Powershell engine Exiting event (ie [System.Management.Automation.PsEngineEvent]::Exiting ) 并在任何时候执行Update-Database时通过其-Action参数自动执行脚本作为响应(但前提是在同一 Powershell session 中)。

有关详细信息和示例,请参阅Register-EngineEvent命令

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/register-engineevent?view=powershell-7

在您的操作脚本中,您可以获得事件详细信息(如$Events[0].MessageData )并搜索文本" Database-Update " ,然后执行您想要的命令作为响应。 如果" Database-Update "文本出现在 session 中的任何意外上下文中,这可能会出错。

您可以在此处查看Get-Event命令详细信息和示例

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-event?view=powershell-7

您可以通过New-PSSession session 命令在本地或远程计算机上设置持久性 session,以便事件订阅者可以考虑在多个文件中执行的命令。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/new-pssession?view=powershell-7

更多关于不同类型的 Powershell 会话

https://www.sconstantinou.com/windows-powershell-sessions-pssessions/

暂无
暂无

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

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