我尝试将IConfiguration
注入迁移(在构造函数中),并获得异常:"没有为此对象定义无参数构造函数。"
任何解决方法?
答案 0 :(得分:11)
您不能,迁移需要能够在您的应用程序的上下文之外运行。
由于Entity-framework命令行工具会分析您的代码但不运行startup.cs类。
也不建议。您的迁移应该简单明了,不依赖于任何东西。如果它会,它可能导致主要的运行时副作用,其中缺少配置可能导致生产中缺少表或列。
如果涉及很多小/平等/手动更改。最好的方法是生成迁移文件。为什么?这样,您的迁移将具有确定性:您知道结果将是什么。如果迁移中的某一行失败,那么简单明了,为什么那么容易(呃)可修复。
答案 1 :(得分:4)
有一种方法可以做您想做的事。在我的方案中,我想通过DbContext在连接字符串中使用数据库名称。使用EF core 2.1.1。 The code is modified from here
创建自定义的MigrationsAssembly服务
dlg.Destroy()
用自定义类替换DbContext中的IMigrationAssembly服务
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using System;
using System.Reflection;
public class ContextAwareMigrationsAssembly : MigrationsAssembly
{
private readonly DbContext context;
public ContextAwareMigrationsAssembly(
ICurrentDbContext currentContext,
IDbContextOptions options,
IMigrationsIdGenerator idGenerator,
IDiagnosticsLogger<DbLoggerCategory.Migrations> logger) : base(currentContext, options, idGenerator, logger)
{
context = currentContext.Context;
}
/// <summary>
/// Modified from http://weblogs.thinktecture.com/pawel/2018/06/entity-framework-core-changing-db-migration-schema-at-runtime.html
/// </summary>
/// <param name="migrationClass"></param>
/// <param name="activeProvider"></param>
/// <returns></returns>
public override Migration CreateMigration(TypeInfo migrationClass, string activeProvider)
{
var hasCtorWithDbContext = migrationClass
.GetConstructor(new[] { typeof(DbContext) }) != null;
if (hasCtorWithDbContext)
{
var instance = (Migration)Activator.CreateInstance(migrationClass.AsType(), context);
instance.ActiveProvider = activeProvider;
return instance;
}
return base.CreateMigration(migrationClass, activeProvider);
}
}
然后,您可以在迁移中添加一个protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<IMigrationsAssembly, ContextAwareMigrationsAssembly>();
}
参数。
DbContext
根据您的情况,您可以将所有public Migration20180801(DbContext context)
{
DatabaseName = context.Database.GetDbConnection().Database;
}
引用替换为DbContext
,并使用IConfiguration
替代中的相关实例。
答案 2 :(得分:0)
如果只是关于您的连接字符串(是吗?),您可能需要检查this answer,这基本上可以在您的启动项目(而非迁移项目)中建议以下代码:>
var myConnectionString = Configuration.GetConnectionString(myConnectionStringName);
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(
myConnectionString ,
x => x.MigrationsAssembly(myDbContextAssemblyName)));