App:Asp.NET Core 1.1.1,EF Core
平台:Visual 2017 5.3.3
身份验证模式:单个用户帐户
按照来自本教程官方团队的ASP.NET命令,以下命令成功运行:
PM> Add-Migration MyFirstMigration -context BloggingContext我们知道,VS2017默认在MyProject\Data文件夹下创建ApplicationDbContext,用于创建用于身份验证的用户表(ASPNETUsers, ASPNETRoles etc...)。但是,当我运行下面的命令时,它首先给出了下面的Error-1。当我遵循第一条错误信息中的说明时,我得到了下面的Error-2。问题:如何使以下命令在不使用的情况下使用IDbContextFactory工作
PM> Add-Migration MyFirstAuthenMigration -context ApplicationDbContext误差1
在'ApplicationDbContext‘上没有找到无参数构造函数。或者向'ApplicationDbContext‘添加无参数构造函数,或者在与'ApplicationDbContext’相同的程序集中添加'IDbContextFactory‘的实现。
在ApplicationDbContext.cs中添加无参数构造函数(如下所示)之后,将得到第二个错误,如下所示:
误差2
没有为此DbContext配置数据库提供程序。可以通过重写DbContext.OnConfiguring方法或在应用程序服务提供程序上使用AddDbContext来配置提供程序。如果使用AddDbContext,那么还要确保DbContext类型在构造函数中接受DbContextOptions对象,并将其传递给DbContext的基本构造函数。
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
//NOTE: I added following constructor after Error 1 shown above
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}发布于 2017-09-05 09:43:00
你不能让它起作用。因为EF需要知道应该使用哪个连接字符串。您可以将连接字符串放入OnModelCreating方法中。当您有多个DB (例如开发、测试和生产)时,这是很糟糕的。或者您实现了IDbContextFactory,它将由EF通过反射加载。
因此,实现IDbContextFactory是更好的选择。只需在有ApplicationDbContext的地方创建它。示例实现。
public class DomainContextFactory : IDbContextFactory<DomainContext>
{
public string BasePath { get; protected set; }
public DomainContext Create()
{
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var basePath = AppContext.BaseDirectory;
return Create(basePath, environmentName);
}
public DomainContext Create(DbContextFactoryOptions options)
=> Create(options.ContentRootPath, options.EnvironmentName);
private DomainContext Create(string basePath, string environmentName)
{
BasePath = basePath;
var configuration = Configuration(basePath, environmentName);
var connectionString = ConnectionString(configuration.Build());
return Create(connectionString);
}
private DomainContext Create(string connectionString)
{
if (string.IsNullOrEmpty(connectionString))
{
throw new ArgumentException($"{nameof(connectionString)} is null or empty", nameof(connectionString));
}
var optionsBuilder = new DbContextOptionsBuilder<DomainContext>();
return Configure(connectionString, optionsBuilder);
}
protected virtual IConfigurationBuilder Configuration(string basePath, string environmentName)
{
var builder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("constr.json")
.AddJsonFile($"constr.{environmentName}.json", true)
.AddEnvironmentVariables();
return builder;
}
protected virtual string ConnectionString(IConfigurationRoot configuration)
{
string connectionString = configuration["ConnectionStrings:DefaultConnection"];
return connectionString;
}
protected virtual DomainContext Configure(string connectionString, DbContextOptionsBuilder<DomainContext> builder)
{
builder.UseSqlServer(connectionString, opt => opt.UseRowNumberForPaging());
DomainContext db = new DomainContext(builder.Options);
return db;
}
DomainContext IDbContextFactory<DomainContext>.Create(DbContextFactoryOptions options)
=> Create(options.ContentRootPath, options.EnvironmentName);
}它可以处理3个配置文件(最终、本地和测试)。
其用法如下:
public override IServiceResult<IList<Rolle>> LoadAllData()
{
using (var db = this.DomainContextFactory.Create())
{
Task<List<Rolle>> rollen = db.Roles
.ToListAsync<Rolle>();
return new ServiceResult<IList<Rolle>>(rollen.Result, rollen.Result.Count);
}
}并且在MSVC内部使用“附加迁移”也是可行的。
https://stackoverflow.com/questions/46030083
复制相似问题