Включение файлов sql при генерации миграций в EF Core - asp.net - PullRequest
0 голосов
/ 16 октября 2019

В настоящее время у нас есть проект, который использует команды EF для автоматической генерации сценария миграции, то есть миграция dotnet ef добавляет InitialCreate

В дополнение к автоматически созданным объектам нам нужно запустить команды sqlиз файлов для генерации хранимых процедур, которые требуются внешним службам.

Достаточно просто добавить следующее к переносу вручную, и это работает локально:

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

Однако это необходимодобавление снова каждый раз, когда мы запускаем построитель миграции (что довольно часто, поскольку часто добавляются новые модели и т. д.), и это не работает при отправке на наши серверы разработки, поскольку они автоматически запускают команды построителя миграции и обновления базы данных.

Есть ли способ заставить EF автоматически включать файлы sql при генерации миграции? Или лучший способ сделать это в целом?

1 Ответ

0 голосов
/ 16 октября 2019

Это наша реализация для выполнения сценариев 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 class:

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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...