无法将 Entity Framework 核心迁移添加到 .NET Standard 2.0 项目

Can't add Entity Framework Core migrations to .NET Standard 2.0 project

我有很多项目的解决方案。 其中之一 (Domain) 是一个 .NET Standard 2.0 项目,我在其中制作了我的 EF Core DbContext 实现,我想为其启用 数据库迁移.

我看到了各种博客和 Q/A 论坛,其中解释了问题,但 none 提议的解决方案似乎对我有用,因为 .NET Core 更新版本或(可能)对我的特定的解决方案配置。

解决方案项目

WindowsService是Startup项目,其中创建了Engine的一个实例并封装到运行作为Windows服务或控制台应用程序(用于调试) .

Engine是真正的核心应用,其中Kestrel自托管Web服务器实例配置为WebAPI并实例化。其他组件也被实例化并保持活动状态(UDP 侦听器、机器看门狗等...)。

WebAPIStartup class 但没有 Program class,因为所有配置和 Web 服务器启动都在 [=21= 中完成] class.

依赖项

第一次尝试是简单地从 PMC 启动 add-migration Initial,并将 Domain 项目作为目标,但它变成了:

Unable to create an object of type 'MyDbContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

然后我按照 问题的建议解决方案,但是:

  1. add-migration Initial 来自PMC,将My WebAPI(没有Program class)设置为启动项目后,变为:

    It was not possible to find any compatible framework version The specified framework 'Microsoft.NETCore.App', version '2.1.0' was not found.

    • Check application dependencies and target a framework version installed at: C:\Program Files\dotnet\
    • Installing .NET Core prerequisites might help resolve this problem: http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
    • The .NET Core framework and SDK can be installed from: https://aka.ms/dotnet-download
    • The following versions are installed: 2.0.5 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] 2.0.6 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] 2.0.7 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] 2.0.9 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] 2.1.2 at [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  2. add-migration Initial 来自 PMC,在将额外的目标框架(netcoreapp2.1)添加到域库项目文件后,导致我遇到与第一次尝试相同的错误。

  3. add-migration Initial 来自 PMC,在添加对 Microsoft.EntityFrameworkCore.SqlServer.Design v1.1.6 的引用后总是会导致与第一次尝试相同的错误。

我该怎么办?

更新

这是删除不必要的库引用后的新 Domain.csproj 文件。

<ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" />
    <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
</ItemGroup>

所有项目中的所有库都是最新的。

您的 class 库的 csproj 文件应该至少包含这个包。确保您的版本与所有 Microsoft 程序包匹配。 2.1.02.1.1(此时最新)

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
  </ItemGroup>

</Project>

Package Manager Console 中,将 默认项目 设置为要迁移到的 class 库。它是控制台右上角的下拉菜单 window。另外,请确保您的启动项目是具有数据库连接信息的项目。

如果启动项目没有您想要构建的 DbContext 的实例,您将收到错误消息,因为它不知道如何实现 DbContext .您应该像这样在 Startup.cs 中注册 DbContext

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString));

然后,运行 命令 Add-Migration InitialCreate。这将为您的迁移搭建脚手架,它应该将一个文件夹添加到您的 class 库中。

之后,运行 Update-Database 它应该应用迁移。

如果您仍有问题。确保您使用的是最新的 SDK 运行。 https://www.microsoft.com/net/download

可以在文档中找到更多信息。 https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/

  1. here 下载并安装适当的 RuntimeSDK - 我猜你现在需要 .NET Core 2.1.302
  2. Microsoft.EntityFrameworkCore.SqlServer.Design 不再需要,因为它包含在 SDK 中。 CLI csproj 字段中的 EntityFrameworkCore 参考也不需要。
  3. 确保您 Manage NuGet packages window 显示所有更新。
  4. 在您的 Web 项目的任何地方添加 IDesignTimeDbContextFactory 接口的实现 - 它会被自动找到并用于 EF Add-Migration(或 dotnet ef... 类似物) Package Manager Console

    中的命令
    public class DesignTimeActivitiesDbContextFactory : IDesignTimeDbContextFactory<ActivitiesDbContext>
    {
        public ActivitiesDbContext CreateDbContext(string[] args)
        {
            DbContextOptionsBuilder<ActivitiesDbContext> builder = new DbContextOptionsBuilder<ActivitiesDbContext>();
    
            var context = new ActivitiesDbContext(
                builder
                .UseSqlServer("Data Source=(local)\LocalDB;Initial Catalog=DB_name;Integrated Security=True;")
                .Options);
    
            return context;
        }
    }
    

要从您的 appsettings 配置文件中读取连接字符串,您可以执行以下操作:

public class DesignTimeActivitiesDbContextFactory : IDesignTimeDbContextFactory<ActivitiesDbContext>
{
    public ActivitiesDbContext CreateDbContext(string[] args)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(Path.Combine(Directory.GetCurrentDirectory()))
            .AddJsonFile("appsettings.Development.json", optional: false);

        var config = builder.Build();

        var optionsBuilder = new DbContextOptionsBuilder<ActivitiesDbContext>()
            .UseSqlServer(config.GetConnectionString("DefaultConnection"));

        return new ActivitiesDbContext(optionsBuilder.Options);
    }
}

注意:在上面的代码工厂中,将使用 appsettings.Development.json 文件中定义的连接字符串值。连接名称是 DefaultConnection。换句话说,这个设计时间工厂用于 Code First 命令,如 Add-MigrationUpdate-Database,等等...)并将它们应用到为 [=30= 配置的数据库连接] 环境。