EntityFramework.Docs icon indicating copy to clipboard operation
EntityFramework.Docs copied to clipboard

Document AddDbContextFactory

Open ajcvickers opened this issue 5 years ago • 6 comments

ajcvickers avatar Jul 20 '20 21:07 ajcvickers

any update on this documentation?

ddieppa avatar Sep 22 '20 15:09 ddieppa

I found some references here https://docs.microsoft.com/en-us/aspnet/core/blazor/blazor-server-ef-core?view=aspnetcore-5.0

VaclavElias avatar Sep 22 '20 15:09 VaclavElias

@ajcvickers Is lazy loading supported when using IDbContextFactory<TContext>? I have lazy loading without proxies setup and is throwing exception when accessing a virtual object of an entity.

Exception details: System.InvalidOperationException: 'Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.LazyLoadOnDisposedContextWarning': An attempt was made to lazy-load navigation property 'Features.Car' after the associated DbContext was disposed. This exception can be suppressed or logged by passing event ID 'CoreEventId.LazyLoadOnDisposedContextWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.'

I have also tried enabling lazy loading proxies while adding (services.AddDbContextFactory<TContext>(...)) but the virtual object(s) are not loaded.

services.AddDbContextFactory<AutomobileDbContext>(options => {
                options.UseSqlServer(config.GetConnectionString("AutomobileConnectionString"));
                options.EnableSensitiveDataLogging();
                options.UseLazyLoadingProxies();
            }, ServiceLifetime.Singleton);

Thanks in advance.

Edit: Let me know if you'd like me to open a different issue for this one.

bmoteria avatar Oct 20 '20 19:10 bmoteria

@bmoteria I suspect that you are running into issues because the DbContext instances have different lifetimes. Specifically, when using AddDbContext with all the default options, the DbContext will be disposed when the current service scope ends, which is coupled to the current request in ASP.NET Core. So your context will not be disposed until the request ends.

When using AddDbContextFactory and then creating a DbContext instance from the factory it becomes up to the application to dispose the context when it is no longer being used. However, this is likely before the end of the request, which means if something (say a view) is using that context for lazy-loading, then it will end up trying to use a context that has already been disposed.

ajcvickers avatar Oct 27 '20 22:10 ajcvickers

@ajcvickers Thanks for the great information! Earlier I had wrapped the query within _dbContextFactory.CreateDbContext() using statement inside a repository (which had disposed the DbContext before exiting the method). This is why I was receiving System.InvalidOperationException exception.

Now, I manually create instance of DbContext using IDbContextFactory before execution of my service method and dispose it manually before the end of my service method (I ended up creating a BaseRepository - which helps in creating and disposing DbContext; and a BaseService - which trigger the methods inside BaseRepository).

bmoteria avatar Nov 04 '20 13:11 bmoteria

See comment here: https://github.com/dotnet/efcore/pull/21246#issuecomment-734296254

ajcvickers avatar Nov 30 '20 20:11 ajcvickers