web-dev-qa-db-ja.com

Entity Framework Coreを使用して移行SQLスクリプトを実行する方法

移行を適用するSQLスクリプトにアクセスできないという問題に直面しました。これが私の移行コードです:

 public partial class AddSomethingMigration : Migration
{
    private const string MIGRATION_SQL_SCRIPT_FILE_NAME = @"Migrations\Scripts\20170710123314_AddSomethingMigration.sql";

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        string sql = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, MIGRATION_SQL_SCRIPT_FILE_NAME));
        migrationBuilder.Sql(File.ReadAllText(sql));
    }
}

したがって、ローカルマシンでパッケージマネージャコンソールを使用すると、すべて正常に動作します。しかし、環境にデプロイすると、ファイルに不一致が生じます。

EF移行を介して静的SQLスクリプトを自動的に実行することはできますか、それともSQLクエリをコードにインラインで貼り付ける必要がありますか?

11
shkapo

この質問に対するいくつかの回答が見つかりました。

  1. スクリプトをプロジェクトリソースとして追加し、次のように使用します。

        string sql = Resources._20170630085940_AddMigration;
        migrationBuilder.Sql(sql);
    

.sqlがアセンブリに埋め込まれるため、このオプションはあまり良くありません。

  1. .csproj構造のNet Coreプロジェクトを使用する場合、itemgroupをxmlに追加できます。

    <ItemGroup> <Content Include="Migrations\**\*.sql" CopyToPublishDirectory="PreserveNewest" /><!-- CopyToPublishDirectory = { Always, PreserveNewest, Never } --></ItemGroup>
    

そして、次のようにファイルへのパスを指定します:

Path.Combine(AppContext.BaseDirectory, relativePath)
14
shkapo

これは、EmbeddedResourceを使用するメソッドのアップグレードです。主なアイデアは、マイグレーションと同じ名前の抽象クラスとSQLファイルを使用することです。

public abstract class SqlMigration : Migration
{
    protected sealed override void Up(MigrationBuilder migrationBuilder)
    {
        var Assembly = Assembly.GetExecutingAssembly();
        var type = GetType();
        var regex = new Regex($@"{Regex.Escape(type.Namespace)}\.\d{{14}}_{Regex.Escape(type.Name)}\.sql");

        var resourceName = Assembly.GetManifestResourceNames().FirstOrDefault(x => regex.IsMatch(x));
        using var stream = Assembly.GetManifestResourceStream(resourceName);
        using var reader = new StreamReader(stream);
        var sqlResult = reader.ReadToEnd();
        migrationBuilder.Sql(sqlResult);
    }
}

正規表現には、実際のタイプの名前と名前空間を使用します。継承クラスは次のようになります。

public partial class RunSqlScript : SqlMigration
{
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        // Down code here
    }
}

プロジェクトは次のようになります。

enter image description here

0
4lexKislitsyn