我在ASP.NET CORE 1.0.0中做了一个项目,我正在使用EntityFrameworkCore。我有单独的程序集,我的项目结构如下所示:
ProjectSolution
-src
-1 Domain
-Project.Data
-2 Api
-Project.Api
我的Project.Api
是Startup
类
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ProjectDbContext>();
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ProjectDbContext>()
.AddDefaultTokenProviders();
}
我的Project.Data项目中有DbContext
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);
}
}
当我尝试进行初始迁移时,我收到此错误:
&#34;您的目标项目&#39; Project.Api&#39;与您的迁移程序集“Project.Data&#39;”不匹配。更改目标项目或更改迁移程序集。 使用DbContextOptionsBuilder更改迁移程序集。例如。 options.UseSqlServer(connection,b =&gt; b.MigrationsAssembly(&#34; Project.Api&#34;))。默认情况下,迁移程序集是包含DbContext的程序集。 使用程序包管理器控制台的默认项目下拉列表或执行&#34; dotnet ef&#34;将目标项目更改为迁移项目。来自包含迁移项目的目录。&#34;
在看到此错误后,我尝试执行Project.Api
中的此命令:
dotnet ef --startup-project ../Project.Api --assembly&#34; ../../ 1 Data / Project.Data&#34;迁移添加初始
我收到了这个错误:
&#34;意外的值&#39; ../../ 1 Domain / Project.Data&#39;选项&#39;组装&#39;&#34;
我没有t know why I get this error, when I try to execute the command with the
- assembly`参数。
我无法从其他程序集创建初始迁移,我搜索了有关它的信息但没有得到任何结果。
有人有类似的问题吗?
答案 0 :(得分:35)
所有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"))
答案 1 :(得分:16)
我遇到了同样的问题,直到我注意到在包管理器控制台顶部栏=&gt; &#34;默认项目&#34;应该是&#34; Project.Data&#34;而不是&#34; Project.API&#34;。
一旦你定位了&#34; Project.Data&#34;从下拉列表中运行迁移你应该没问题。
答案 2 :(得分:8)
使用EF Core 2,您可以轻松地将 Web 项目与 Data (DbContext)项目分开。实际上,您只需要实现 IDesignTimeDbContextFactory 接口。根据{{3}}, 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
您可以找到更多详情Microsoft docs。但是,此博客文章使用的是废弃的类,而不是 IDesignTimeDbContextFactory 。
答案 3 :(得分:5)
答案 4 :(得分:5)
目前我认为EF仅支持在尚未加入类库的项目上添加迁移。
对于想要将迁移添加到项目内特定文件夹的其他人,只需旁注:
EF CLI 尚不支持此功能。我试过了--data-dir
,但它没有用。
唯一有效的方法是使用Package Manager控制台:
-OutputDir
命令参数,.e.g。,Add-Migration InitConfigurationStore -OutputDir PersistedStores/ConfigurationStore
命令会将mgiry输出到我项目中的文件夹'PersistedStores / ConfigurationStore'。 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)
)
);
...
}
答案 5 :(得分:2)
以下命令对我有用。我正在使用VS Code,并运行以下命令:
SocialApp.Models> dotnet ef migrations add InitialMigartion --startup-project ../SocialApp.API
答案 6 :(得分:1)
(ASP.NET Core 2 +)
有同样的问题。 这是我所做的:
从将包含迁移(Project.B)的项目中引用包含DbContext(Project.A)的项目。
将现有的迁移从Project.A迁移到Project.B (如果您没有迁移,请先创建它们)
在Project.A中配置迁移程序集
options.UseSqlServer( connectionString, x => x.MigrationsAssembly(“ Project.A”)))
假设您的项目位于同一父文件夹中:
dotnet ef migrations add Init --project ../AskGoo.Data -c DbContext
现在迁移到Project.B
来源:Microsoft
答案 7 :(得分:1)
这是针对EF Core 3.x。
基于this的Ehsan Mirsaeedi答案和this的Ales Potocnik Hahonina评论,我也设法使Add-Migration起作用。
我将Identity Server 4用作NuGet软件包,并且该软件包中有两个数据库上下文。 这是实现IDesignTimeDbContextFactory接口的类的代码:
public class PersistedGrantDbContextFactory : IDesignTimeDbContextFactory<PersistedGrantDbContext>
{
public PersistedGrantDbContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var dbContextBuilder = new DbContextOptionsBuilder<PersistedGrantDbContext>();
var connectionString = configuration.GetConnectionString("db");
dbContextBuilder.UseSqlServer(connectionString, b => b.MigrationsAssembly("DataSeeder"));
return new PersistedGrantDbContext(dbContextBuilder.Options, new OperationalStoreOptions() { ConfigureDbContext = b => b.UseSqlServer(connectionString) });
}
}
与Ehsan Mirsaeedi的答案相比,我修改了这些内容: 我添加了MigrationsAssembly:
dbContextBuilder.UseSqlServer(connectionString, b => b.MigrationsAssembly("DataSeeder"));
“ DataSeeder”是我的启动项目的种子和迁移项目的名称。
我在连接字符串中添加了一个ConfigureDbContext属性设置的选项对象:
return new PersistedGrantDbContext(dbContextBuilder.Options, new OperationalStoreOptions() { ConfigureDbContext = b => b.UseSqlServer(connectionString) });
现在可以这样使用: '添加迁移-Context PersistedGrantDbContext
此时,创建迁移后,可以在具有以下方法的迁移项目中为此创建服务:
public async Task DoFullMigrationAsync()
{
using (var scope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var persistedGrantDbContextFactory = new PersistedGrantDbContextFactory();
PersistedGrantDbContext persistedGrantDbContext = persistedGrantDbContextFactory.CreateDbContext(null);
await persistedGrantDbContext.Database.MigrateAsync();
// Additional migrations
...
}
}
希望我能帮助一个人。
干杯
汤姆
答案 8 :(得分:1)
您要做的就是像这样修改您的ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ProjectDbContext>(item => item.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("Project.Api")));
services.AddIdentity<IdentityUser, IdentityRole>()
.AddEntityFrameworkStores<ProjectDbContext>()
.AddDefaultTokenProviders();
}
默认情况下,VS将使用存储DbContext的项目的程序集。上面的更改只是告诉VS使用您的API项目的程序集。
您仍然需要将API项目设置为默认启动项目,方法是在解决方案资源管理器中右键单击该项目,然后选择“设置为启动项目”
答案 9 :(得分:1)
我的是一个单一的 .net 核心网络项目。
必须确保 1 件事来解决此错误。项目中必须存在以下类。
public class SqlServerContextFactory : IDesignTimeDbContextFactory<SqlServerContext>
{
public SqlServerContext CreateDbContext(string[] args)
{
var currentEnv = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{ currentEnv ?? "Production"}.json", optional: true)
.Build();
var connectionString = configuration.GetConnectionString("MsSqlServerDb");
var optionsBuilder = new DbContextOptionsBuilder<SqlServerContext>();
//var migrationAssembly = typeof(SqlServerContext).Assembly.FullName;
var migrationAssembly = this.GetType().Assembly.FullName;
if (connectionString == null)
throw new InvalidOperationException("Set the EF_CONNECTIONSTRING environment variable to a valid SQL Server connection string. E.g. SET EF_CONNECTIONSTRING=Server=localhost;Database=Elsa;User=sa;Password=Secret_password123!;");
optionsBuilder.UseSqlServer(
connectionString,
x => x.MigrationsAssembly(migrationAssembly)
);
return new SqlServerContext(optionsBuilder.Options);
}
}
注意迁移程序集名称。
//var migrationAssembly = typeof(SqlServerContext).Assembly.FullName;
我已经注释掉了。这就是我的罪魁祸首。需要的是以下内容。
var migrationAssembly = this.GetType().Assembly.FullName;
有了它,以下两个命令就可以很好地工作了。
Add-Migration -StartupProject MxWork.Elsa.WebSqLite -Context "SqlServerContext" InitialMigration
Add-Migration InitialMigration -o SqlServerMigrations -Context SqlServerContext
如果您想参考此类项目,请查看此git hub link
您应该在那里找到一个名为 Elsa.Guides.Dashboard.WebApp50.zip 的项目。下载该网络应用程序。
答案 10 :(得分:0)
我也面临着类似的问题,尽管答案似乎很直接,但以某种方式却无法解决。 我的答案类似于@Ehsan Mirsaeedi,但DbContextFactory类的更改很小。我没有在API的Startup类中添加迁移程序集名称,而是在DbContextFactory类中提到过,该类是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。我想肯定有一些接线问题。
答案 11 :(得分:0)
Add-Migration NewMigration -Project MyApp.Migrations
答案 12 :(得分:0)
使用CLI命令添加迁移:
dotnet ef migrations add NewMigration --project YourAssemplyName
使用PMC命令添加迁移:
Add-Migration NewMigration -Project YourAssemplyName
答案 13 :(得分:0)
我已通过在Startup.cs中添加以下行来解决此问题。希望它也能对您有所帮助。我用过Postgres,可以用Sql Server代替
- hosts: all
vars:
test: "Test Successfull"
repo_dir: /media/disk1/sandbox/xyz
path: /media/disk1/sandbox/xyz/api
tasks:
- debug:
msg: "{{ test.split()[0] }} {{ test.split()[1] }}"
- name: Running npm install in directory "{{ path }} and {{ repo_dir }}/lib as well"
command: npm install
args:
chdir: "{{ item }}"
loop:
- "{{ path }}"
- "{{ repo_dir }}/lib"
become_user: yash
become: yes
答案 14 :(得分:0)
dotnet ef update-database --startup-project Web --project 数据
Web
是我的启动项目Data
是我的类库答案 15 :(得分:-1)