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:
- Use private fields like compiled queries in context classes
- Make use of
HttpContext.Itemsto 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.
WriteDbContextandReadDbContextis a big red flag suggesting you're trying to apply some "best practices" without thinking about it.private fields like compiled queries in context classesthat's a C# question and why do you think you need compiled queries? That won't make the generated SQL fasterSet<>(), 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'tUse private fieldsis a simple C# question - you can, but you can't use these in derived classes.Make use of HttpContext.Itemsthere's no HttpContext to begin with so no.HttpContextrefers 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 methodsWriteDbContext 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 withcontext.ChangeTracker.AutoDetectChangesEnabled = false;or useAsNoTracking()in a query.