Home > OS >  ASP.NET Core- The DbContext of type 'ApplicationDbContext' cannot be pooled because it doe
ASP.NET Core- The DbContext of type 'ApplicationDbContext' cannot be pooled because it doe

Time:08-19

I am implementing Entity Framework Code-First in ASP.NET Core-6 Web API. I am using IdentityDbContext, and I have this code:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long, IdentityUserClaim<long>, ApplicationUserRole, IdentityUserLogin<long>, IdentityRoleClaim<long>, IdentityUserToken<long>>
{
    private readonly ICurrentUserService _currentUser;
    private readonly IDateTime _dateTime;

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
      : base(options)
    {

    }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, ICurrentUserService currentUser, IDateTime dateTime) : base(options)
    {
        _currentUser = currentUser;
        _dateTime = dateTime;
    }

    public DbSet<Transaction> Transactions { get; set; }
    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public DbSet<ApplicationRole> ApplicationRoles { get; set; }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly);
        base.OnModelCreating(builder);

        builder.ApplyConfiguration(new TransactionConfigurations());
        builder.ApplyConfiguration(new ApplicationUserConfigurations());
        builder.ApplyConfiguration(new ApplicationUserRoleConfigurations());
        builder.ApplyConfiguration(new ApplicationRoleConfigurations());
    }
    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
    {
        foreach (var item in ChangeTracker.Entries<AuditableEntity>())
        {
            switch (item.State)
            {
                case EntityState.Modified:
                    item.Entity.LastModifiedBy = _currentUser.UserName;
                    item.Entity.LastModifiedAt = _dateTime.Now;
                    break;

                case EntityState.Added:
                    item.Entity.CreatedBy = _currentUser.UserName;
                    item.Entity.CreatedAt = _dateTime.Now;
                    break;

                case EntityState.Deleted:
                    item.Entity.DeletedBy = _currentUser.UserName;
                    item.Entity.DeletedAt = _dateTime.Now;
                    item.Entity.IsDeleted = true;
                    break;

                default:
                    break;
            }
        }
        return await base.SaveChangesAsync(cancellationToken);
    }
}

When I want to create Migration using Add-Migration InitialCreate -OutputDir Persistence\Migrations

I got this error:

The DbContext of type 'ApplicationDbContext' cannot be pooled because it does not have a public constructor accepting a single parameter of type DbContextOptions or has more than one constructor.

How do I get it resolved?

Thanks

CodePudding user response:

When you use context pooling, usually via AddDbContextPool, your context can only have a single constructor, and it must only take a single parameter of type DbContextOptions<TContext>. Of course, you need other objects but there is a solution. An EF Core DbContext has tight integration with dependency injection, so you can do this in your constructor instead:

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
    _currentUser = this.GetService<ICurrentUserService>();
    _dateTime = this.GetService<IDateTime>();
}

CodePudding user response:

Your problem is caused by wanting to inject services into the DbContext, which isn't that terrific of an idea.

Wrap it around: create a handler to handle the DbContext.SavingChanges event and update your entities in there.

See Callback on SaveChanges in EFCore? for an implementation thereof.

Also, assuming Transactions inherits AuditableEntity, I'm not sure ChangeTracker.Entries<AuditableEntity>() will do what you expect it to.

  • Related