公開されたDLLからEF Core RC2ツールを実行する方法はありますか?

asp.net-core entity-framework-core

質問

.Net Core RC1アプリケーションを公開した後、project.jsonで指定されたコマンドには、展開後に実行できる対応する.cmdファイルが作成されていました(web.cmdやef.cmdなど)。私の場合は、展開ターゲットで次のEntity Frameworkコマンドを実行します。

dotnet ef database update -c MyContext

これは、ソースコードを含むフォルダからこれを実行するとうまく動作しますが、発行後はコンパイルされたDLL内でコマンドが見つからないようです。 RC2でのコマンドの変更についての私の理解は、「ツール」をdotnet - *。dllという名前のスタンドアロンアプリケーションとしてコンパイルし、CLI経由で実行できることです。エンティティフレームワークのコアツールは、公開された出力で実行可能なDLLとしてどのように公開できますか?

参考までに、私のビルド/展開のワークフローは次のとおりです。

TeamCity

dotnet restore => dotnet build => dotnet test => dotnet publish

Octopus Deploy

アップロードパッケージ=> EFデータベース更新=>など

受け入れられた回答

プロジェクトで同じ問題が発生しましたが、いくつかの理由から、アプリケーションの起動時にマイグレーションが自動的に実行されることは望ましくありません。

それを解決するために、私はProgram.csを2つの引数を取るように更新しProgram.csた(完全なコードは以下にリストされています)

  • --ef-migrate 、保留中の移行をすべて適用する
  • --ef-migrate-check 、すべての移行が適用されているかどうかを検証する

引数が存在する場合、EFアクションが適用され、プログラムが終了します。そうでない場合、Webアプリケーションが起動されます。

コマンドラインの解析を容易にするために、 Microsoft.Extensions.CommandLineUtilsパッケージに依存することに注意してください。

Octopusをデプロイするためには、別々の場所(つまり、実行中の移行用とWebホスティング用の2つ)にパッケージを2回公開することができます。私たちのケースでは、 "post deploy powershell script"にコンテンツを追加しました

$env:ASPNETCORE_ENVIRONMENT="#{Octopus.Environment.Name}"
dotnet example-app.dll --ef-migrate

ドッカーの文脈ではそれは完全に働くだろう

docker run -it "example-app-container" dotnet example-app.dll --ef-migrate

名前空間と使用を除く完全なProgram.cs:

//Remember to run: dotnet add package Microsoft.Extensions.CommandLineUtils
public class Program
{
    public static void Main(string[] args)
    {
        var commandLineApplication = new CommandLineApplication(false);
        var doMigrate = commandLineApplication.Option(
            "--ef-migrate",
            "Apply entity framework migrations and exit",
            CommandOptionType.NoValue);
        var verifyMigrate = commandLineApplication.Option(
            "--ef-migrate-check",
            "Check the status of entity framework migrations",
            CommandOptionType.NoValue);
        commandLineApplication.HelpOption("-? | -h | --help");
        commandLineApplication.OnExecute(() =>
        {
            ExecuteApp(args, doMigrate, verifyMigrate);
            return 0;
        });
        commandLineApplication.Execute(args);
    }

    private static void ExecuteApp(string[] args, CommandOption doMigrate, CommandOption verifyMigrate)
    {
        Console.WriteLine("Loading web host");
        var webHost = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        if (verifyMigrate.HasValue() && doMigrate.HasValue())
        {
            Console.WriteLine("ef-migrate and ef-migrate-check are mutually exclusive, select one, and try again");
            Environment.Exit(2);
        }

        if (verifyMigrate.HasValue())
        {
            Console.WriteLine("Validating status of Entity Framework migrations");
            using (var context = webHost.Services.GetService<DatabaseContext>())
            {
                var pendingMigrations = context.Database.GetPendingMigrations();
                var migrations = pendingMigrations as IList<string> ?? pendingMigrations.ToList();
                if (!migrations.Any())
                {
                    Console.WriteLine("No pending migratons");
                    Environment.Exit(0);
                }

                Console.WriteLine("Pending migratons {0}", migrations.Count());
                foreach (var migration in migrations)
                {
                    Console.WriteLine($"\t{migration}");
                }

                Environment.Exit(3);
            }
        }

        if (doMigrate.HasValue())
        {
            Console.WriteLine("Applyting Entity Framework migrations");
            using (var context = webHost.Services.GetService<DatabaseContext>())
            {
                context.Database.Migrate();
                Console.WriteLine("All done, closing app");
                Environment.Exit(0);
            }
        }

        // no flags provided, so just run the webhost
        webHost.Run();
    }
}

人気のある回答

ここでは、この問題に対する解決策がある非常に有用な記事があります

それは私のために働いた(私は少しコマンドを微調整しなければならなかったが、それは私に開始する良い基盤を与えた)。

ef.dllef.dllを渡すことによってef.dll dotnet ef database updateコマンドを複製することができdotnet ef database update (例えば、あなたのnugetフォルダから直接(または、あなたが機械を稼働させているので、あなたがnugetを持っていないならどこかから)あなたの.dllには、 dotnet.exe (またはそれに相当するもの)へのいくつかの追加パラメータ(下記参照)を含む移行が含まれています。

完全性のためにここには.cmd(blogpostから!)

set EfMigrationsNamespace=%1
set EfMigrationsDllName=%1.dll
set EfMigrationsDllDepsJson=%1.deps.json
set DllDir=%cd%
set PathToNuGetPackages=%USERPROFILE%\.nuget\packages
set PathToEfDll=%PathToNuGetPackages%\microsoft.entityframeworkcore.tools.dotnet\1.0.0\tools\netcoreapp1.0\ef.dll

dotnet exec --depsfile .\%EfMigrationsDllDepsJson% --additionalprobingpath %PathToNuGetPackages% %PathToEfDll% database update --assembly .\%EfMigrationsDllName% --startup-assembly .\%EfMigrationsDllName% --project-dir . --content-root %DllDir% --data-dir %DllDir% --verbose --root-namespace %EfMigrationsNamespace%

(このcmdがblogpostにある場合はbash版)

Btw。このアプローチは多くのgithubの問題でも言及されていました。https : //github.com/aspnet/EntityFramework.Docs/issues/328 https://github.com/aspnet/EntityFramework.Docs/issues/180

ps: Ben Dayブログでこれを見つけたので、すべてのクレジットはBenに送られます!



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ