简体   繁体   English

.NET 标准库是否支持 EF Core 添加迁移?

[英]Is EF Core Add Migration Supported from .NET Standard Library?

We have been trying to run EF Core Migration in .Net Standard 1.6 class library, but it has been failing.我们一直在尝试在 .Net Standard 1.6 类库中运行 EF Core Migration,但一直失败。 But same passes very well in .Net Core 1.1 class library.但是在 .Net Core 1.1 类库中同样通过得很好。

Is EF Migration supported in .NET STANDARD? .NET STANDARD 是否支持 EF 迁移?

The documentation covers this case as know issue /limitation when the DbContext is placed inside an netstandardx.y Class Library.DbContext放置在netstandardx.y类库中时,文档将这种情况称为已知问题/限制。

Workaround 1 - Use an app as the startup project解决方法 1 - 使用应用程序作为启动项目

If you have an existing .NET Core App or .NET Framework App (including an ASP.NET Core Web Application), you can use it as the startup project.如果您有现有的 .NET Core 应用程序或 .NET Framework 应用程序(包括 ASP.NET Core Web 应用程序),则可以将其用作启动项目。 If not, you can create a new one just for use with the .NET Command Line Tools.如果没有,您可以创建一个新的,仅用于 .NET 命令行工具。 Specify a startup project that is a "runnable app."指定作为“可运行应用程序”的启动项目。 Example: console示例:控制台

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

Workaround 2 - Cross-target a runnable framework解决方法 2 - 跨目标可运行框架

Add an additional target framework to the class library project.向类库项目添加额外的目标框架。 This can a version of either .NET Core App or .NET Framework.这可以是 .NET Core App 或 .NET Framework 的一个版本。 To make the project a .NET Core App, add the "netcoreapp1.0" framework to project like in the sample below: XML要使项目成为 .NET Core 应用程序,请将“netcoreapp1.0”框架添加到项目中,如下例所示: XML

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

When targeting .NET Framework, ensure you project targets version 4.5.1 or newer.面向 .NET Framework 时,请确保您的项目面向版本 4.5.1 或更高版本。 XML XML

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

For you EF Core Package Manager Console Tools users who are seeing the following errors:对于您看到以下错误的 EF Core 包管理器控制台工具用户:

Startup project 'MyNetStandardLibrary' targets framework '.NETStandard'.启动项目“MyNetStandardLibrary”针对框架“.NETStandard”。 There is no runtime associated with this framework, and projects targeting it cannot be executed directly.没有与此框架关联的运行时,针对它的项目无法直接执行。 To use the Entity Framework Core Package Manager Console Tools with this project, add an executable project targeting .NET Framework or .NET Core that references this project, and set it as the startup project;要将 Entity Framework Core Package Manager Console Tools 与此项目一起使用,请添加一个面向 .NET Framework 或 .NET Core 的可执行项目并引用此项目,并将其设置为启动项目; or, update this project to cross-target .NET Framework or .NET Core.或者,更新此项目以跨目标 .NET Framework 或 .NET Core。

OR或者

Your target project 'MyNetCoreApp' doesn't match your migrations assembly 'MyNetStandardLibrary'.您的目标项目“MyNetCoreApp”与您的迁移程序集“MyNetStandardLibrary”不匹配。 Either change your target project or change your migrations assembly.更改您的目标项目或更改您的迁移程序集。


The documentation reveals the cause of these errors: 文档揭示了这些错误的原因:

The target project is where any files are added (or in some cases removed).目标项目是添加(或在某些情况下删除)任何文件的地方。 The target project defaults to the Default project selected in Package Manager Console, but can also be specified using the -Project parameter.目标项目默认为在包管理器控制台中选择的默认项目,但也可以使用 -Project 参数指定。

The startup project is the one emulated by the tools when executing your project's code.启动项目是在执行项目代码时由工具模拟的项目。 It defaults to one Set as StartUp Project in Solution Explorer.它默认为在解决方案资源管理器中设置为启动项目。 It can also be specified using the -StartupProject parameter.也可以使用 -StartupProject 参数指定。

In a nutshell, you need to set your StartUp Project to a project that has a .NET runtime (.NET Core in this case), then make sure you set your .NET Standard project as the Package Manager Console > Default Project.简而言之,您需要将启动项目设置为具有 .NET 运行时的项目(在本例中为 .NET Core),然后确保将 .NET Standard 项目设置为包管理器控制台 > 默认项目。

Example CLI Solution:示例 CLI 解决方案:

Add-Migration MyMigration -Project MyNetStandardLibrary -StartupProject MyNetCoreApp

Non-CLI Solution:非 CLI 解决方案:

  1. Right-clicking the .NET Core app in your project右键单击项目中的 .NET Core 应用
  2. Clicking Set as StartUp Project单击设置为启动项目
  3. Open the Package Manager Console打开包管理器控制台
  4. Select your .NET Standard project from the Default Project dropdown in the Package Manager Console从包管理器控制台的默认项目下拉列表中选择您的 .NET Standard 项目
  5. Run your CLI command (Add-Migration, dotnet ef migrations add, etc.)运行您的 CLI 命令(Add-Migration、dotnet ef migrations add 等)

I haven't tried with .Net Standard 1.6 but It does work for 2.0.我还没有尝试过 .Net Standard 1.6,但它确实适用于 2.0。

Microsoft.EntityFrameworkCore.Tools.DotNet needs to be added to each of your class libraries that have a DbContext in them. Microsoft.EntityFrameworkCore.Tools.DotNet需要添加到每个包含DbContext中。 Right click the project and select Edit *.csproj .右键单击该项目并选择Edit *.csproj Then, add the following:然后,添加以下内容:

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

You can see a more in-depth tutorial here: EF 7 Migrations with multiple DBContexts您可以在此处查看更深入的教程: EF 7 Migrations with multiple DBContexts

All that right but there is a complexity and i would like to give an explanation.好吧,但有一个复杂性,我想给出一个解释。

Case: Asp.Net Core, I have a standard library that containing Db-Context.案例:Asp.Net Core,我有一个包含 Db-Context 的标准库。 I want to migrate this context but standard library doesn't accepting migration directly, needs a startup project.我想迁移这个上下文,但标准库不直接接受迁移,需要一个启动项目。

Solution: startup project is able to create migration indirectly解决方案:启动项目可以间接创建迁移

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

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

We will choose Caller Project from the Package Manager Console DropDown but it will create the migration file in the library project.我们将从 Package Manager Console DropDown 中选择 Caller Project,但它会在库项目中创建迁移文件。 After that don't choose other project from the drop down and run update from the caller project directly without any argument .之后不要从下拉列表中选择其他项目并直接从调用者项目运行更新而不带任何参数

Update-Database

try it strange but true尝试一下奇怪但真实

Update: I have upgraded my project Asp.net EntityFrameworkCore 3.1.3 to 3.1.4 and those on up hasnt worked firectly and gave an error :更新:我已将我的项目 Asp.net EntityFrameworkCore 3.1.3 升级到 3.1.4,上面的那些没有正常工作并给出错误:

The EntityFramework package is not installed on project EntityFramework 包未安装在项目上

and this error和这个错误

Unable to create an object of type 'DomainDbContext'.无法创建类型为“DomainDbContext”的对象。 For the different patterns supported at design time对于设计时支持的不同模式

This is an EntityFramework.Core application!这是一个 EntityFramework.Core 应用程序! I have installed also EntityFramework to the standart library.我还安装了 EntityFramework 到标准库。 But it couldnt understand and restarted VS This time it needed to install entityframework to starter MVC (Web) project.但是它无法理解并重新启动VS 这次需要将entityframework安装到启动MVC(Web)项目中。 I can't do that.我不能那样做。 I decide to add a new Console Application to solving this requirement.我决定添加一个新的控制台应用程序来解决这个需求。 And created below application for this并为此创建了以下应用程序

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!");
    }
}

This time it has worked correctly!这次它正常工作了! with the above commands again :) cheer再次使用上述命令:) 欢呼

@Tseng, thank you! @Tseng,谢谢! Here are explicit instructions.这里有明确的说明。

Edit project file:编辑项目文件:

<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>

Then add design factory:然后添加设计工厂:

 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;
        }
    }

Then build.然后构建。

Then open command prompt, navigate to your projects folder, and run:然后打开命令提示符,导航到您的项目文件夹,然后运行:

dotnet ef migrations add InitialCreate

Now there should be an auto-generated migrations folder.现在应该有一个自动生成的迁移文件夹。 Love it!爱它!

shameful for Microsoft. 对微软来说是可耻的。

i transferred my dbcontext to console app in my dotnet core solution. 我将dbcontext转移到我的dotnet核心解决方案中的控制台应用程序。

my solution has 5 projects in it. 我的解决方案中有5个项目。

then i run dotnet ef migrations add CreateDatabase 然后我运行dotnet ef migrations add CreateDatabase

i use vs code and dotnet cli. 我使用vs代码和dotnet cli。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM