Tal*_*aul 13 entity-framework-core asp.net-core
发布.Net Core RC1应用程序后,project.json中指定的命令具有为其创建的相应.cmd文件,这些文件可在部署后执行(例如web.cmd和ef.cmd).在我的例子中,我想在我的部署目标上运行以下Entity Framework命令:
dotnet ef database update -c MyContext
Run Code Online (Sandbox Code Playgroud)
当我从包含源代码的文件夹运行它时,这工作正常,但是在发布后,它似乎没有在编译的DLL中找到命令.我对RC2命令变化的理解是"工具"可以编译为名为dotnet - *.dll的独立应用程序,并且可以通过CLI执行.如何将实体框架核心工具公开为已发布输出中的可执行DLL?
仅供参考,我的构建/部署工作流程如下:
TeamCity的
dotnet restore => dotnet build => dotnet test => dotnet publish
八达通部署
上传包=> EF更新数据库=>等
Maj*_*jor 20
不幸的是,EF Core 迁移 s*cks,很多......我已经看到了大量的解决方案,但让我们列出它们。因此,您可以在没有 Visual Studio 的情况下运行和部署 EF 迁移。以下都不是完美的解决方案都有一些警告:
IDesignTimeDbContextFactory<DbContext>接口才能使其工作。还要确保您的部署服务器上有EF.dll和Microsoft.EntityFrameworkCore.Design.dll。链接的脚本正在寻找许多文件夹中的那些。最好是在构建期间将它从 .nuget 文件夹复制到您的工件。听起来很复杂,是的……但链接脚本有很大帮助。dbContext.Database.Migrate();dotnet ef migrations script --output <pathAndFile>.sql --context <DbContextName> --idempotent。输出是一个 SQL 文件,可以手动执行,也可以通过 CI/CD 管道中的脚本执行。.csproj文件所在的工作目录中运行非常重要。所以它需要源代码!此外,您必须稍微更改代码。需要执行IDesignTimeDbContextFactory<DbContext>。更新:在 .NET 5 中有一些改进。现在更容易实现和使用IDesignTimeDbContextFactory,但最重要的是微软修复了这个错误。现在可以将 SQL 连接字符串作为args. 因此,如果您实现了,IDesignTimeDbContextFactory<T>那么将它与 .NET CLI 和 EF 工具一起使用很简单:
dotnet ef database update --context <DbContextName> --project "**/<ProjectName>.csproj" -- "<SQL connection will be passed into args[0]>"
同样重要的是要强调这仅适用于 .NET 5 并且还需要源代码! 您还可以将它与选项 6(生成 SQL 脚本)一起使用。
第二个烦人的问题一旦实现IDesignTimeDbContextFactory<T>,所有ef命令都会发现(甚至在开发过程中从 Visual Studio 运行的命令)。如果您需要来自 args[0] 的 SQL 连接字符串,您必须在开发过程中migrations add或任何其他ef命令中传递它!
对不起,名单太长了。但希望它有所帮助。
nov*_*ver 10
我在项目中遇到了同样的问题,但由于多种原因,我不希望迁移在应用程序启动时自动运行.
为了解决它,我更新Program.cs了两个参数(完整代码列在下面)
--ef-migrate,以应用所有挂起的迁移,和--ef-migrate-check,以验证是否已应用所有迁移如果存在参数,则应用EF操作并退出程序,否则启动Web应用程序.
请注意,它取决于Microsoft.Extensions.CommandLineUtils软件包以简化命令行解析.
对于章鱼部署,然后可以将包发布两次到单独的位置 - 一个用于运行迁移,另一个用于webhosting.在我们的例子中,我们添加了一个带有内容的"post deploy powershell脚本"
$env:ASPNETCORE_ENVIRONMENT="#{Octopus.Environment.Name}"
dotnet example-app.dll --ef-migrate
Run Code Online (Sandbox Code Playgroud)
在docker环境中,它也可以完美地工作
docker run -it "example-app-container" dotnet example-app.dll --ef-migrate
Run Code Online (Sandbox Code Playgroud)
完整的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();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
自最初的问题提出以来已经过去了很多时间,现在有更好的方法来处理 CI/CD 场景中的 ef 迁移。
有一个名为“bundles”的官方工具。
您所要做的就是构建一个捆绑包
dotnet ef migrations bundle
Run Code Online (Sandbox Code Playgroud)
稍后,您可以传递目标数据库连接字符串来执行捆绑包
.\efbundle.exe --connection 'Data Source=(local)\MSSQLSERVER;Initial Catalog=Blogging;User ID=myUsername;Password=myPassword'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2928 次 |
| 最近记录: |