darxis / EntityFramework.LazyLoading

LazyLoading for EF Core
MIT License
21 stars 4 forks source link

Question: Don't we lose compiled query caching? #15

Open voodookoop opened 7 years ago

voodookoop commented 7 years ago

PerDbContextCompiledQueryCache makes compiled queries per context, obviously as its name suggests. As @darxis pointed out earlier, ICompiledQueryCache by default is registered as a singleton in EF Core (see _coreServices Dictionary), now it is overridden to be Scoped by LazyLoadingOptionsExtension. In many scenarios, DbContexts are living for just a short time interval, therefore we lose compiled query caching by opening another one, however asking just the same query many times possibly. I haven't ran load tests against this scenario, but won't this affect performance?

Connected issue: in current EF core dev branch CompiledQueryCache accepts only an IMemoryCache parameter in its constructor therefore from the next version, LL won't be able to get the ICurrentDbContext from IDbContextServices parameter anymore (see current CompiledQueryCache.cs).

darxis commented 7 years ago

@voodookoop Yes, you are right. The query cache contains entries, and these entries are also responsible for materializing the entity after querying the database (at least that's what I have figured out).

Performance will get affected for sure with this approach, especially with WebApplications when a DbContext is created per HTTP request.

What we could do is to fill the LazyLoading properties/fields, after the entity has been materialized, not in the materializer itself. This approach will not affect the performance because all the compiled queries will get cached. For this, research has to be done to check where exactly we could hook EF to inject the LazyLoading entity properties/fields after the entity was materialized.

Antoher approach is to create a static cache of base compiled queries that will be used by our PerDbContextCompiledQueryCache. The base ones means the ones without any LazyLoading-related logic. When EF tries to get a compiled query from our PerDbContextCompiledQueryCache, this cache will get the base compiled query from the static cache, and insert to it only LazyLoading-related stuff.

I'm going to do some reasearch on the two approaches above, to check whether they are possible at all, and then list the pros and cons of both.

@voodookoop Maybe you have thought of another solution to this problem?

PS: For now we focus on getting the EntityFramework.LazyLoading library fully working (no bugs) on EF Core v1.1.1. When a new release of EF Core (v2.0?) will get officially released, we would focus on the new one.