使用不同的程序集添加迁移

问题描述 投票:26回答:9

我正在ASP.NET CORE 1.0.0中做一个项目,我正在使用EntityFrameworkCore。我有单独的程序集,我的项目结构如下所示:

ProjectSolution
   -src
      -1 Domain
         -Project.Data
      -2 Api
         -Project.Api

在我的Project.ApiStartup

public void ConfigureServices(IServiceCollection services)
    {            
        services.AddDbContext<ProjectDbContext>();

        services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ProjectDbContext>()
                .AddDefaultTokenProviders();
    }

DbContext在我的Project.Data项目中

public class ProjectDbContext : IdentityDbContext<IdentityUser>
{
    public ProjectDbContext(DbContextOptions<ProjectDbContext> options) : base(options)
    {

    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {

        var builder = new ConfigurationBuilder();
        builder.SetBasePath(Directory.GetCurrentDirectory());
        builder.AddJsonFile("appsettings.json");
        IConfiguration Configuration = builder.Build();

        optionsBuilder.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection"));
        base.OnConfiguring(optionsBuilder);
    }
}

当我尝试进行初始迁移时,出现此错误:

“您的目标项目'Project.Api'与您的迁移程序集'Project.Data'不匹配。更改目标项目或更改迁移程序集。使用DbContextOptionsBuilder更改迁移程序集。例如options.UseSqlServer(connection,b = > b.MigrationsAssembly(“Project.Api”))。默认情况下,迁移程序集是包含DbContext的程序集。使用程序包管理器控制台的“默认项目”下拉列表或执行将目标项目更改为迁移项目来自包含迁移项目的目录中的“dotnet ef”。“

在看到此错误后,我尝试执行位于Project.Api中的此命令:

dotnet ef --startup-project ../Project.Api --assembly“../../1 Data / Project.Data”迁移添加初始

我收到了这个错误:

选项'assembly'的“意外值'../../ Domain / Project.Data'”

我dont know why I get this error, when I try to execute the command with the-assembly`参数。

我不能从其他程序集创建初始迁移,我搜索了有关它的信息,但没有得到任何结果。

有人有类似的问题吗?

c# asp.net-core entity-framework-core ef-migrations
9个回答
39
投票

所有EF命令都有this check

if (targetAssembly != migrationsAssembly) 
       throw MigrationsAssemblyMismatchError;

targetAssembly =您正在操作的目标项目。在命令行中,它是当前工作目录中的项目。在程序包管理器控制台中,它是在该窗口窗格右上角的下拉框中选择的任何项目。

migrationsAssembly =包含迁移代码的程序集。这是可配置的。默认情况下,这将是包含DbContext的程序集,在您的情况下是Project.Data.dll。如错误消息所示,您有两个选项可以解决此问题

1 - 更改目标组件。

cd Project.Data/
dotnet ef --startup-project ../Project.Api/ migrations add Initial

// code doesn't use .MigrationsAssembly...just rely on the default
options.UseSqlServer(connection)

2 - 更改迁移程序集。

cd Project.Api/
dotnet ef migrations add Initial

// change the default migrations assembly
options.UseSqlServer(connection, b => b.MigrationsAssembly("Project.Api"))

19
投票

我有同样的问题,直到我注意到在包管理器控制台顶部栏=>“默认项目”应该是“Project.Data”而不是“Project.API”。

从下拉列表中定位“Project.Data”并运行迁移后,您应该没问题。


10
投票

使用EF Core 2,您可以轻松地将Web项目与Data(DbContext)项目分开。实际上,您只需要实现IDesignTimeDbContextFactory接口。根据Microsoft docs,IDesignTimeDbContextFactory是:

用于创建派生DbContext实例的工厂。实现此接口以为没有公共默认构造函数的上下文类型启用设计时服务。在设计时,可以创建派生的DbContext实例,以便启用特定的设计时体验,例如迁移。设计时服务将自动发现启动程序集中的此接口的实现或与派生上下文相同的程序集。

在底部的代码片段中,您可以看到我在我的Data项目中定义的DbContextFactory的实现:

public class DbContextFactory : IDesignTimeDbContextFactory<KuchidDbContext>
{
    public KuchidDbContext CreateDbContext(string[] args)
    {
        var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();

        var dbContextBuilder = new DbContextOptionsBuilder<KuchidDbContext>();

        var connectionString = configuration.GetConnectionString("Kuchid");

        dbContextBuilder.UseSqlServer(connectionString);

        return new KuchidDbContext(dbContextBuilder.Options);
    }
}

现在,我可以通过将我的Web项目设置为StartUp项目并在Package Manager控制台中选择我的Data项目来初始化EF迁移。

Add-Migration initial

你可以找到更多细节here。但是,此博客文章使用的是过时的类而不是IDesignTimeDbContextFactory。


5
投票

我遇到了同样的问题,发现了this

我们是您尝试在类库上运行迁移吗?我也是如此。事实证明这还不支持,所以我们需要解决它。

编辑:我在this git repo找到了解决方案


5
投票

目前我认为EF仅支持在尚未上类库的项目上添加迁移。

对于想要将迁移添加到项目内特定文件夹的其他人,请注意:

EF CLI尚不支持此功能。我尝试了--data-dir,但它没有用。

唯一有效的方法是使用Package Manager控制台:

  1. 选择您的默认项目
  2. 使用-OutputDir命令参数,例如,Add-Migration InitConfigurationStore -OutputDir PersistedStores/ConfigurationStore命令会将mgiry输出到我项目中的文件夹'PersistedStores / ConfigurationStore'。

Updates as of 10/12/2017

public void ConfigureServices(IServiceCollection services)
{
    ...

    string dbConnectionString = services.GetConnectionString("YOUR_PROJECT_CONNECTION");
    string assemblyName = typeof(ProjectDbContext).Namespace;

    services.AddDbContext<ProjectDbContext>(options =>
        options.UseSqlServer(dbConnectionString,
            optionsBuilder =>
                optionsBuilder.MigrationsAssembly(assemblyName)
        )
   );

   ...
}

3
投票

(ASP.NET Core 2+)

有同样的问题。这是我做的:

  1. 从包含迁移的项目(Project.B)引用包含DbContext(Project.A)的项目。
  2. 将现有迁移从Project.A移动到Project.B(如果没有迁移 - 首先创建它们)
  3. 在Project.A中配置迁移程序集

options.UseSqlServer(connectionString,x => x.MigrationsAssembly(“Project.A”));

假设您的项目位于同一个父文件夹中:

  1. dotnet ef migrations add Init --project ../AskGoo.Data -c DbContext

迁移现在转到Project.B

资料来源:Microsoft


1
投票
Add-Migration NewMigration -Project MyApp.Migrations

0
投票

我面临着类似的问题,虽然答案看起来很简单但不知何故他们没有用。我的答案类似于@Ehsan Mirsaeedi,DbContextFactory类中的变化很小。我在DbContextFactory类中提到过,而不是在API的Startup类中添加迁移程序集名称,它是Data项目(类库)的一部分。

public class DbContextFactory : IDesignTimeDbContextFactory<KuchidDbContext>
{
   public KuchidDbContext CreateDbContext(string[] args)
   {
       var configuration = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json")
          .Build();

       var dbContextBuilder = new DbContextOptionsBuilder<KuchidDbContext>();

       var connectionString = configuration.GetConnectionString("connectionString");

       var migrationAssemblyName= configuration.GetConnectionString("migrationAssemblyName");

       dbContextBuilder.UseSqlServer(connectionString, o => o.MigrationAssembly(migrationAssemblyName));

       return new KuchidDbContext(dbContextBuilder.Options);
   }
}

您需要'Microsoft.Extensions.Configuration'和'Microsoft.Extensions.Configuration.Json'才能使SetBasePath和AddJsonFile扩展工作。

注意:我觉得这只是一个解决方法。它应该以某种方式从启动类中拾取DbContextOptions。我想肯定有一些接线问题。


-1
投票

对于拥有多个启动项目的所有人。

请注意,您需要将目标项目设置为启动项目 - Project.Api(形成问题示例)应该是启动项目。

希望能帮助别人:)

© www.soinside.com 2019 - 2024. All rights reserved.