【问题标题】:Is EF Core Add Migration Supported from .NET Standard Library?.NET 标准库是否支持 EF Core 添加迁移?
【发布时间】:2017-11-09 21:18:39
【问题描述】:

我们一直在尝试在 .Net Standard 1.6 类库中运行 EF Core Migration,但一直失败。但在 .Net Core 1.1 类库中同样通过。

.NET STANDARD 是否支持 EF 迁移?

【问题讨论】:

    标签: c# asp.net-core entity-framework-core .net-standard


    【解决方案1】:

    DbContext 放置在netstandardx.y 类库中时,文档将这种情况称为know issue/limitation。

    解决方法 1 - 使用应用作为启动项目

    如果您有现有的 .NET Core 应用程序或 .NET Framework 应用程序(包括 ASP.NET Core Web 应用程序),则可以将其用作启动项目。如果没有,您可以创建一个仅用于 .NET 命令行工具的新工具。 指定作为“可运行应用程序”的启动项目。 示例:控制台

    dotnet ef migrations list --startup-project ../MyConsoleApp/
    

    解决方法 2 - 跨目标可运行框架

    向类库项目添加一个额外的目标框架。这可以是 .NET Core App 或 .NET Framework 的版本。 要使项目成为 .NET Core 应用程序,请将“netcoreapp1.0”框架添加到项目中,如下例所示: XML

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>netcoreapp1.0;netstandard1.4</TargetFrameworks>
      </PropertyGroup>
    </Project>
    

    以 .NET Framework 为目标时,请确保您的项目目标为 4.5.1 或更高版本。 XML

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFrameworks>net46;netstandard1.4</TargetFrameworks>
      </PropertyGroup>
    </Project>
    

    【讨论】:

    • 我使用 Entity Framework Core 的次数越多,我就越想知道它是如何在它所处的状态下一直到第 2 版的。
    • @BradleyUffner:这是由于工具定位和初始化上下文的方式。 EF Core 需要一个用于依赖注入的连接字符串,需要对其进行编译(以确保其可执行),然后由控制台应用程序启动。 iirc 在 2.0 中进行了许多更改,这将解决这个问题。见EF Core 2.0: design-time DbContext discovery changes公告
    • @BradleyUffner 即使使用 .Net 2.0 我也有同感。 MS 的营销策略浪费了大量的开发人员时间。不专注于使 .Net 本身更强大,stackoverflow.com/questions/46232820/…
    • @BradleyUffner 在这个 exp 级别,即使是 Asp.Net Web API 似乎也不完整stackoverflow.com/questions/46319844/…
    • 请注意其他面临此问题的人。我尝试按照建议直接在同一 TargetFramework 属性组上添加框架,但收到错误消息。我最终做的是创建另一个 your_targetframework 并且成功了。
    【解决方案2】:

    对于遇到以下错误的 EF Core 包管理器控制台工具用户:

    启动项目“MyNetStandardLibrary”以框架“.NETStandard”为目标。没有与此框架相关联的运行时,并且针对它的项目无法直接执行。要在此项目中使用 Entity Framework Core 包管理器控制台工具,请添加一个针对 .NET Framework 或引用此项目的 .NET Core 的可执行项目,并将其设置为启动项目;或者,将此项目更新为跨目标 .NET Framework 或 .NET Core。

    您的目标项目“MyNetCoreApp”与您的迁移程序集“MyNetStandardLibrary”不匹配。更改您的目标项目或更改您的迁移程序集。


    documentation 揭示了这些错误的原因:

    目标项目是添加(或在某些情况下删除)任何文件的位置。目标项目默认为 Package Manager Console 中选择的 Default 项目,但也可以使用 -Project 参数指定。

    启动项目是工具在执行项目代码时模拟的项目。它在解决方案资源管理器中默认为一个 Set as StartUp Project。也可以使用 -StartupProject 参数指定。

    简而言之,您需要将您的启动项目设置为具有 .NET 运行时(在本例中为 .NET Core)的项目,然后确保将您的 .NET Standard 项目设置为包管理器控制台 > 默认项目.

    示例 CLI 解决方案:

    Add-Migration MyMigration -Project MyNetStandardLibrary -StartupProject MyNetCoreApp
    

    非 CLI 解决方案:

    1. 右键单击项目中的 .NET Core 应用
    2. 点击设置为启动项目
    3. 打开包管理器控制台
    4. 从包管理器控制台的默认项目下拉列表中选择您的 .NET Standard 项目
    5. 运行 CLI 命令(Add-Migration、dotnet ef migrations add 等)

    【讨论】:

      【解决方案3】:

      没关系,但是有一个复杂性,我想给出一个解释。

      案例:Asp.Net Core,我有一个包含 Db-Context 的标准库。我想迁移 此上下文但标准库不直接接受迁移,需要启动项目。

      解决方案:启动项目可以间接创建迁移

      Enable-Migrations MyMigration -Project DB-ContextProjectNameThatIsStandartLib -StartupProject CallerExecutableProjectName_LikeMVCWebProjectOrConsole
      
      Add-Migration MyMigration -Project DB-ContextProjectNameThatIsStandartLib -StartupProject CallerExecutableProjectName_LikeMVCWebProjectOrConsole
      

      我们将从包管理器控制台下拉菜单中选择调用者项目,但它将在库项目中创建迁移文件。 之后不要从下拉列表中选择其他项目并直接从调用者项目运行更新没有任何参数

      Update-Database
      

      试试奇怪但真实的

      更新: 我已将我的项目 Asp.net EntityFrameworkCore 3.1.3 升级到 3.1.4,而那些启动并没有正常工作并给出错误:

      EntityFramework 包没有安装在项目中

      还有这个错误

      无法创建“DomainDbContext”类型的对象。为了 设计时支持的不同模式

      这是一个 EntityFramework.Core 应用程序!我还安装了 EntityFramework 到标准库。但它无法理解并重新启动 V.S. 这次它需要安装 entityframework 来启动 MVC (Web) 项目。我不能那样做。我决定添加一个新的控制台应用程序来解决这个要求。并为此创建了下面的应用程序

      install-Package Microsoft.Extensions.Configuration
      Install-Package Microsoft.Extensions.Configuration.Json
      Install-Package Microsoft.Extensions.Configuration.CommandLine
      Install-Package Microsoft.Extensions.Configuration.EnvironmentVariables
      
      class Program
      {
          public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<DomainDbContext>
          {
              public DomainDbContext CreateDbContext(string[] args)
              {
                  IConfigurationRoot configuration = new ConfigurationBuilder()
                      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                      .AddEnvironmentVariables()
                      //.SetBasePath(Directory.GetCurrentDirectory())
                      //.AddJsonFile("appsettings.json")
                      .Build();
                  var builder = new DbContextOptionsBuilder<DomainDbContext>();
                  var connectionString = configuration.GetConnectionString("DefaultConnection");
                  builder.UseSqlServer(connectionString);
                  return new DomainDbContext(builder.Options);
              }
          }
      
          static void Main(string[] args)
          {
              Console.WriteLine("Hello World!");
          }
      }
      

      这次它工作正常!再次使用上述命令:) 欢呼

      【讨论】:

        【解决方案4】:

        我没有尝试使用 .Net Standard 1.6,但它确实适用于 2.0。

        Microsoft.EntityFrameworkCore.Tools.DotNet 需要添加到每个包含DbContext 的类库中。右键单击项目并选择Edit *.csproj。然后,添加以下内容:

          <ItemGroup>
            <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0-preview2-final" />
          </ItemGroup>
        

        您可以在此处查看更深入的教程:EF 7 Migrations with multiple DBContexts

        【讨论】:

        • 您的解决方案不适用于 .NET Core v2.1。如果您尝试使用 NuGet 将 Microsoft.EntityFrameworkCore.Tools.DotNet 包安装到您的 DbContext 所在的 .NET Standard 项目中,则会出现错误,指出它仅与 netcoreapp2.0 兼容。此外,如果您手动编辑 .csproj 文件并添加对 DotNetCliToolReference 的引用,则会出现过时警告
        • @CheshireCat 是的,那个包现在已经过时了。您可以安装 nuget 包 Microsoft.EntityframeworkCore.Tools 以获得相同的功能。
        • @ToddSkeleton 请你看看我的新question,因为我仍然无法让它工作......
        【解决方案5】:

        @Tseng,谢谢!这里有明确的说明。

        编辑项目文件:

        <Project Sdk="Microsoft.NET.Sdk">
          <PropertyGroup>
            <TargetFramework>netstandard2.0</TargetFramework>
          </PropertyGroup>
          <PropertyGroup>
            <TargetFramework>netcoreapp2.0</TargetFramework>
          </PropertyGroup>
          <ItemGroup>
            <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
            <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" />
            <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
            <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
          </ItemGroup>
          <ItemGroup>
            <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
          </ItemGroup>
        </Project>
        

        然后添加设计工厂:

         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);Initial Catalog=Activities;Integrated Security=False;User ID=user;Password=pw;Connect Timeout=30;Encrypt=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;")
                        .Options);
        
                    return context;
                }
            }
        

        然后构建。

        然后打开命令提示符,导航到您的项目文件夹,然后运行:

        dotnet ef migrations add InitialCreate
        

        现在应该有一个自动生成的迁移文件夹。喜欢它!

        【讨论】:

          猜你喜欢
          • 2018-02-10
          • 1970-01-01
          • 2021-03-07
          • 2017-05-30
          • 1970-01-01
          • 2019-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多