0

I have a base class called BaseDbContext. I derived two classes from this: WriteDbContext and ReadDbContext. Both contexts have compiled queries as private members in WriteDbContext and ReadDbContext:

public class ReadDbContext(DbContextOptions<ReadDbContext> options) : BaseDbContext(options) 
{
    private static readonly Func<BaseDbContext, string, string, Task<SampleDto>> SampleQuery =
        EF.CompileAsyncQuery((BaseDbContext baseDbContext, string id, string name) =>
            baseDbContext.Samples
                .Where(c => c.Id == id && c.name == name)
                .Select(c => new Sample
                {
                    SystemId = c.SystemId,
                })
                .FirstOrDefault()
        );
    
    public async Task<SampleDto> GetSampleAsync(string id, string name)
    {
        return await SampleQuery(this, id, name);
    }
}

WriteDbContext also contains the same exact code.

Can I do the following things when I want to use DbContext pooling:

  1. Use private fields like compiled queries in context classes
  2. Make use of HttpContext.Items to store some information to log

What are all the limitations of DbContext pooling?

edit:

I build APIs. The application serves a lot of traffic and I want to achieve more performance so that is why I want to look into database context pooling.

I read this article https://dev.to/mohammadkarimi/how-dbcontext-pooling-works-4goc and similar other articles which talked about the limitations I mentioned. So, I wanted to know more information about how storing something HttpContext.Items and private members affect database context pooiling

There are two different connection string of reader instance and writer instance. So, I think I have to have two contexts.

6
  • 1
    Why do you think you need a base class or any kind of pooling in the first place? A DbContext is a Unit-of-Work, not a database connection. The very mention of WriteDbContext and ReadDbContext is a big red flag suggesting you're trying to apply some "best practices" without thinking about it. private fields like compiled queries in context classes that's a C# question and why do you think you need compiled queries? That won't make the generated SQL faster Commented Feb 27 at 8:18
  • DbContext pooling doesn't reuse or pool database connections at all. Connection pooling is handled by the ADO.NET drivers. The DbContext doesn't even use a connection until it has to either read or persist data. DbContext pooling is used to reuse the entity metadata in really complex scenarios. When you create a new DbContext instance the metadata of all DbSet properties is calculated on the spot and cached. If you use Set<>(), the metadata creation is delayed. DbContext pooling is used to avoid the cost of metadata creation when that really matters. If you have 5 entities, it doesn't Commented Feb 27 at 8:22
  • As for the 2 questions, they have nothing to do with pooling. Use private fields is a simple C# question - you can, but you can't use these in derived classes. Make use of HttpContext.Items there's no HttpContext to begin with so no. HttpContext refers to the current HTTP request. There's no such request in non web apps, background services or any type that isn't involved in processing a request. An HttpContext instance exists in controllers, Razor pages or middleware, only while the request is alive. It's not a good way of transferring data between methods Commented Feb 27 at 8:27
  • WriteDbContext also contains the same exact code. then you don't need it at all. Given that a DbContext is a Unit-of-Work, what you ask is how to not persist changes in the UoW. To do that, disable change tracking. In EF Core you can disable that upon configuration with context.ChangeTracker.AutoDetectChangesEnabled = false; or use AsNoTracking() in a query. Commented Feb 27 at 8:29
  • On the other hand, if your real intention is to use CQRS, this is the wrong way. Command and Query Separation doesn't refer to repository or DbContext methods. It says that the actual code, all the way up to the UI, that retrieves and displays data is separate from the Commands that modify it. You have a CreateCustomer or UpgradeCustomerStatus Command that isn't related to the Customer, Loyalty, CustomerLoyaltyHistory etc entities. Or the Order, Product etc entities needed at checkout. You may well need different entities so different DbContexts to handle the different use cases Commented Feb 27 at 8:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.