【问题标题】:EF Core - Running migrations without sources - Equivalent of EF6's migrate.exeEF Core - 在没有源的情况下运行迁移 - 相当于 EF6 的 migrate.exe
【发布时间】:2020-12-30 12:20:47
【问题描述】:

是否可以从包含迁移和 dbcontext 的 DLL 运行 ef 迁移?我想在不需要 project.json 和源代码的情况下针对我的构建工件运行dotnet ef database update

换句话说,我正在寻找相当于 EF6 的 migrate.exe https://msdn.microsoft.com/en-us/data/jj618307.aspx

【问题讨论】:

  • 您是否尝试并得到任何错误?
  • @HaithamShaddad:是的,No executable found matching command "dotnet-ef" 但我猜,当你没有 project.json 时,这是正常的。
  • 是的,dotnet ef 需要在 project.json 存在的项目目录中运行,但是为什么需要从 dll 中运行呢?这意味着您的代码已发布并且应该使用自动迁移,或者您应该从数据库中备份
  • @HaithamShaddad:持续集成管道。在我想运行数据库迁移的阶段,我没有资源。在部署它们之前,我想更新数据库并仅在成功时进行部署。使用 EF6 和 migrate.exe 我能够创建这样的管道。
  • 我已经写了一个关于可能性的非常详细的答案here

标签: .net entity-framework .net-core


【解决方案1】:

我的团队同事找到了一种方法,可以让您在没有源的情况下在构建工件上运行迁移。以下命令为我们替换 migrate.exe

dotnet exec 
  --runtimeconfig ./HOST.runtimeconfig.json 
  --depsfile ./HOST.deps.json Microsoft.EntityFrameworkCore.Design.dll
  --assembly ./DB_CONTEXT_DLL.dll 
  --startup-assembly ./HOST.dll --data-dir ./ 
  --root-namespace DB_CONTEXT_NAMESPACE 
  --verbose database update --context DB_CONTEXT_CLASS -e development 

2.1.x 版本更新:

dotnet exec 
   --runtimeconfig ./HOST.runtimeconfig.json 
   --depsfile ./HOST.deps.json /PATH/TO/microsoft.entityframeworkcore.tools/.../ef.dll 
   --verbose database update --context DB_CONTEXT_CLASS
   --assembly ./DB_CONTEXT_DLL.dll 
   --startup-assembly ./HOST.dll --data-dir ./

【讨论】:

  • 嗨,我尝试了这种方法,但出现以下错误 Unhandled Exception: System.MissingMethodException: Entry point not found in assembly 'Microsoft.EntityFrameworkCore.Design, Version=1.1.2.0, Culture=neutral , PublicKeyToken=adb9793829ddae60'。对于上述解决方案,您使用的是哪个版本?
  • 这里是命令 dotnet exec --runtimeconfig ./Dummy.WebAPI.runtimeconfig.json --depsfile ./Dummy.WebAPI.deps.json Microsoft.EntityFrameworkCore.Design.dll --assembly ./ Dummy.Data.dll --startup-assembly ./Dummy.WebAPI.dll --data-dir ./ --root-namespace Dummy.Data --verbose database update --context DummyContext -e development
  • 我目前正在使用 EF 的 v1.1.2,这里是适用于我们的 CLI:dotnet exec --runtimeconfig ./HOST.runtimeconfig.json --depsfile ./AboveCloud.WebApi.deps.json ef.dll --verbose database update --context DB_CONTEXT_CLASS -e production --assembly DB_CONTEXT_DLL ,但我们也复制了这个包:cp /root/.nuget/packages/microsoft.entityframeworkcore.tools.dotnet/1.0.0/tools/netcoreapp1.0/ef.dll bin/Release/netcoreapp1.1/publish
  • 我们不会在类中对连接字符串进行硬编码。那么,这些参数中的哪一个告诉 dotnet exec 到数据库服务器的连接信息?该连接(又名连接字符串)信息存储在哪里?它在 .json 文件中吗?
  • 仍然适用于 .NET 5。还可以指定连接字符串--verbose database update --context ApplicationDbContext --connection "Server=srv;Database=db;User Id=user;Password=pswd;" 或制作脚本文件--verbose migrations script --context ApplicationDbContext --idempotent --output migrations.sql
【解决方案2】:

似乎不可能只用DLL运行dotnet ef database update,如果你使用docker,实际版本的运行时microsoft/dotnet:1.1.0-preview1-runtime没有安装sdk(使用dotnet ef database update命令)。

在不使用dotnet ef database update 的情况下更新数据库的一个选项是在一些默认操作或启动例程中执行下面的命令。

_dbContext.Database.Migrate();

【讨论】:

  • 嗨,我终于采用了这种方法并且它正在工作。谢谢。
  • 这似乎不起作用@AbiP 你做了什么来允许这个?
  • 抱歉,我无法理解您的问题。但这就是我所做的。我从 ConfigureServices 方法内部调用了 context.Database.Migrate()。现在没有方便的代码来粘贴它。让我知道这是否有帮助。
  • @AbiP 抱歉,我不知道 ConfigureServices 在哪里?
  • 我假设您正在使用 dotnet core。在 startup.cs 类中,您应该找到一个 configureService 方法。我指的是这个method.string
【解决方案3】:

我碰巧使用工厂来获取上下文,所以根据 Richardo 的回答创建了一个这样的类。我将它用作单例,并在服务启动时调用它的 ApplyMigrations 方法。

using System;
using Microsoft.EntityFrameworkCore;

namespace Nhs.Digital.Cwt.MultiStreamPublisher
{
    public class MigrationApplier
    {
        private IMyContextFactory _contextFactory;

        public MigrationApplier(IMyContextFactory contextFactory)
        {
            _contextFactory = contextFactory ?? throw new ArgumentNullException($"{nameof(contextFactory)} was null");
        }

        public void ApplyMigrations()
        {
            if (_contextFactory != null)
            {
                using (var context = _contextFactory.Create())
                {
                    _contextFactory = null;
                    context.Database.Migrate();
                }
            }
        }
    }
}

该死的遇到了问题,因为我的部署脚本希望数据库在那里,以便可以向其中添加数据库权限。所以看起来我必须为部署脚本编写一个小型控制台应用程序,用于在添加数据库权限之前创建数据库。克服痛苦编写代码。

【讨论】:

    【解决方案4】:

    我刚刚创建了一个small utility 来解决这个问题。它适用于任何开箱即用的提供商。唯一的要求是您的程序集必须具有 IDesignTimeDbContextFactory 的公共实现。

    用法很简单,执行src/EFMigrate即可 带有第一个参数的项目是您已发布程序集的路径。

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 2018-08-15
      • 2019-03-20
      • 2015-04-29
      • 1970-01-01
      • 2020-10-02
      • 2015-11-06
      • 1970-01-01
      相关资源
      最近更新 更多