gpt4 book ai didi

entity-framework - Entity Framework Core DbContext 继承问题与构造函数中的 DbOptions

转载 作者:行者123 更新时间:2023-12-04 02:52:04 25 4
gpt4 key购买 nike

在我们的项目中,我们有一个数据库,我们在其中使用 DB First 方法。由于我们使用不会被搭建的功能,我有第二个 DBContext,它继承自生成的 DBContext。这使我可以避免每次发生数据库更改时手动操作生成的数据库上下文。

因此 StartUp 中的类定义和用法如下所示:

  // the db context generated by scaffolding the database
public partial class ApplicationDatabaseContextGenerated : DbContext
{
public ApplicationDatabaseContextGenerated() {}
public ApplicationDatabaseContextGenerated(DbContextOptions<ApplicationDatabaseContextGenerated> options) : base(options) {}

// the db sets scaffolded
}

// the db context used by the app with the extended functionality
public class ApplicationDatabaseContext : ApplicationDatabaseContextGenerated
{

public ILogger<ApplicationDatabaseContext> Logger { get; protected set; }

public ApplicationDatabaseContext() : base() {}

public ApplicationDatabaseContext(DbContextOptions<ApplicationDatabaseContext> options, ILogger<ApplicationDatabaseContext> logger) : base(options)
{
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

// the extended functionality like views and functions

}

// how I use it in startup
public void ConfigureServices(IServiceCollection services)
{
// other things ...

services.AddDbContext<ApplicationDatabaseContext>(options => options.UseNpgsql(Configuration.GetConnectionString("db1-connection")));

// other things ...
}

不幸的是,这会导致编译错误,突出显示 ApplicationDatabaseContext 构造函数的 base(options) 声明:
Error CS1503 Argument 1: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions<... ApplicationDatabaseContext>' to 'Microsoft.EntityFrameworkCore.DbContextOptions<... ApplicationDatabaseContextGenerated>'

我想,让我们聪明一点, ApplicationDatabaseContextGenerated 基本上是一个数据库上下文,并将 ApplicationDatabaseContextGenerated 的构造函数更改为:
  public ApplicationDatabaseContextGenerated(DbContextOptions<DbContext> options) : base(options) {}

不,这也是不允许的,结果是:
Error CS1503 Argument 1: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions<... ApplicationDatabaseContext>' to 'Microsoft.EntityFrameworkCore.DbContextOptions<Microsoft.EntityFrameworkCore.DbContext>'

好的,让我们把两者都当作 DbContext
  // the db context generated by scaffolding the database
public partial class ApplicationDatabaseContextGenerated : DbContext
{
public ApplicationDatabaseContextGenerated() {}
public ApplicationDatabaseContextGenerated(DbContextOptions<DbContext> options) : base(options) {}

// the db sets scaffolded
}

// the db context used by the app with the extended functionality
public class ApplicationDatabaseContext : ApplicationDatabaseContextGenerated
{

public ILogger<ApplicationDatabaseContext> Logger { get; protected set; }

public ApplicationDatabaseContext() : base() {}

public ApplicationDatabaseContext(DbContextOptions<DbContext> options, ILogger<ApplicationDatabaseContext> logger) : base(options)
{
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

// the extended functionality like views and functions

}

漂亮,编译。让我们开始吧,我们得到:
  System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_Model()
at Microsoft.EntityFrameworkCore.Internal.InternalDbQuery`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbQuery`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbQuery`1.System.Linq.IQueryable.get_Provider()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.SingleAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at ... MyMethod(ApplicationDatabaseContext dbContext, CancellationToken cancellationToken) in myfile.cs:line 51
at ... MyOtherMethod in myfile.cs:line 61

那么,如何转换 DbContextOptions 或者如何继承 DbContexts?

最佳答案

DbContextOptions<TContext> 是一个泛型类,与任何类一样,它不支持协方差,因此 DbContextOptions<TDerivedContext> 不能被视为 DbContextOptions<TBaseContext>

解决方案是在基础上下文构造函数中使用非通用 DbContextOptions 类(类似于带有选项的 DbContext 类构造函数):

public ApplicationDatabaseContextGenerated(DbContextOptions options) : base(options) { }

由于 AddDbContext<ApplicationDatabaseContext> 将创建 DbContextOptions<ApplicationDatabaseContext> 类的实例,因此 ApplicationDatabaseContext 类构造函数可以使用 DbContextOptions<ApplicationDatabaseContext>DbContextOptions 选项参数。

关于entity-framework - Entity Framework Core DbContext 继承问题与构造函数中的 DbOptions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54627406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com