C#: Inherit from DbContext in Net Core, Constructor: No database provider has been configured for this DbContext

点点圈 提交于 2020-07-23 06:33:37

问题


I currently have PropertyApplication DbContext as below,

public partial class PropertyContext : DbContext
{
    public PropertyContext()
    {
    }

    public PropertyContext(DbContextOptions<PropertyContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Address> Address { get; set; }
    public virtual DbSet<BoundaryChangeEvent> BoundaryChangeEvent { get; set; }

I would like to inheritance from this PropertyDbContext. Is this being done correctly in the constructor? Attempting to make unit test pass below, it overrides save changes to bring in auditing user information. Just curious if specifically the constructor statements below look correct? Or should I try to attempt option 2 below with AuditablePropertyContext options?

public class AuditablePropertyContext : PropertyContext
{
    private int _user;

    public AuditablePropertyContext()
    {
    }

    public AuditablePropertyContext(DbContextOptions<PropertyContext> options, UserResolverService userService)
        : base(options)
    {
        _user = userService.GetUser();
    }

    public void ApplyCreatedBy()
    {
        var modifiedEntities = ChangeTracker.Entries<ICreatedByUserId>().Where(e => e.State == EntityState.Added);
        foreach (var entity in modifiedEntities)
        {
            entity.Property("CreatedByUserId").CurrentValue = _user;
        }
    }

    public override int SaveChanges()
    {
        ApplyCreatedBy();
        return base.SaveChanges();
    }

}

Option 2:

I was receiving error trying to conduct this,

public AuditablePropertyContext(DbContextOptions<AuditablePropertyContext> options, UserResolverService userService)
    : base(options)
{
    _user = userService.GetUser();
}

Error:

Error CS1503 Argument 1: cannot convert from 'Microsoft.EntityFrameworkCore.DbContextOptions IPTS.PropertyManagement.Infrastructure.Auditable.Data.AuditablePropertyContext' to 'Microsoft.EntityFrameworkCore.DbContextOptions IPTS.PropertyManagement.Infrastructure.Data.PropertyContext '

*Sometimes company utilizes SQL Server, sometimes InMemory, or SQLite

Unit Test is failing:

services.AddSingleton(a =>
{
    var mock = new Mock<IUserResolverService>();
    mock.Setup(b => b.GetUser()).Returns(5);
    return mock.Object;
});

services.AddDbContext<PropertyContext>(
    options => options.UseInMemoryDatabase("Ipts").UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll),
    ServiceLifetime.Singleton);
services.AddSingleton<DbContext, PropertyContext>();


services.AddDbContext<AuditablePropertyContext>(
    options => options.UseInMemoryDatabase("Ipts").UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll),
    ServiceLifetime.Singleton);
services.AddSingleton<AuditablePropertyContext>();

services.RegisterMappingProfiles(new ApplicationServicesMappingProfile(),
    new PropertyManagementDataMappingProfile());
return services;

}

Unit Test: Error

Message: 
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.
Stack Trace: 
DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
DbContext.get_InternalServiceProvider()
DbContext.get_DbContextDependencies()

回答1:


Change the constructor PropertyContext class to the following code:

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

then change the constructor AuditablePropertyContext class to the following code:

  public AuditablePropertyContext(DbContextOptions options, UserResolverService userService)
        : base(options)
    {
        _user = userService.GetUser();
    }

notice: Delete the default constructor in both classes when you don't need it.




回答2:


You could also provide the specialized DbContextOptions<Repo> only on the concrete subtype.

eg

public abstract class BaseRepo: DbContext
{
    public BaseRepo(DbContextOptions options) : base(options)
    {

    }
}


public sealed class Repo : BaseRepo
{
    public Repo(DbContextOptions<Repo> options) : base(options)
    {

    }
}


来源:https://stackoverflow.com/questions/61533464/c-inherit-from-dbcontext-in-net-core-constructor-no-database-provider-has-be

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!