发布.Net Core RC1应用程序后,在project.json中指定的命令为它们创建了相应的.cmd文件,可以在部署后执行这些文件(例如,web.cmd和ef.cmd)。就我而言,我想在部署目标上运行以下Entity Framework命令:
dotnet ef database update -c MyContext
当我从包含源代码的文件夹中运行此文件时,此方法运行良好,但是在发布后,在编译的DLL中似乎找不到该命令。我对RC2命令更改的理解是,“工具”可以作为名为dotnet-*。dll的独立应用程序进行编译,并且可以通过CLI执行。如何在发布的输出中将Entity Framework Core工具公开为可执行DLL?
仅供参考,我的构建/部署工作流程如下:
团队城市
dotnet恢复=> dotnet构建=> dotnet测试=> dotnet发布
章鱼部署
上传包=> EF更新数据库=>等等
我最终在一个项目中遇到了同样的问题,但是由于多种原因,我不希望迁移在应用程序启动时自动运行。
为了解决这个问题,我更新Program.cs
了两个参数(下面列出了完整的代码)
--ef-migrate
,以应用所有待处理的迁移,以及--ef-migrate-check
,以验证是否已应用所有迁移如果存在参数,则将应用EF操作并退出程序,否则将启动Web应用程序。
请注意,它取决于Microsoft.Extensions.CommandLineUtils
软件包,以简化命令行解析。
对于octopus部署,一个人可以将程序包两次发布到不同的位置-一个用于运行迁移,另一个用于虚拟主机。在我们的例子中,我们添加了一个“ post deploy powershell脚本”,其中包含以下内容:
$env:ASPNETCORE_ENVIRONMENT="#{Octopus.Environment.Name}"
dotnet example-app.dll --ef-migrate
在docker上下文中,它也可以完美地工作
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");
//
// Please note that this webHostBuilder below is from an older
// dotnet core version. Newer dotnet cores have a simplified version
// Use that instead and just take the command line parsing stuff with you
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 serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.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 serviceScope = webHost.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<DatabaseContext>())
{
context.Database.Migrate();
Console.WriteLine("All done, closing app");
Environment.Exit(0);
}
}
}
// no flags provided, so just run the webhost
webHost.Run();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句