DbContextScope icon indicating copy to clipboard operation
DbContextScope copied to clipboard

Unable to use a non-interfaced DbContext with DbContextScope

Open starmandeluxe opened this issue 8 years ago • 4 comments

I am using .NET Core 1.1 and EF Core, in which my MyDbContext simply inherits from EntityFrameworkCore.DbContext. Unfortunately, DbContextScope expects only an EntityFramework.DbContextScope.IDbContext. How do I resolve this?

I tried implementing the OnConfiguring method in MyDbContext and manually provided the connection string, and while this does get it working, I don't like having to provide the connection string inside there since it's being handled by .NET Core's Startup.cs already:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer("connection string here"));

starmandeluxe avatar May 31 '17 00:05 starmandeluxe

Hi, I have the same problem. How to forward connection string to dbContext using REST .net core? Could you explain how do you do it in your .NET Core project with DbContextScope? Thanks in advance.

Patryx avatar Jul 21 '17 08:07 Patryx

+1

kemmis avatar Aug 03 '17 17:08 kemmis

My solution/workaround:

You can achieve this by implementing a IDbContextFactory like this:

public class MagicDbContextFactory : IDbContextFactory
{
    private readonly IServiceProvider serviceProvider;

    public MagicDbContextFactory(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }

    TDbContext IDbContextFactory.CreateDbContext<TDbContext>()
    {
        return serviceProvider.GetService<TDbContext>();
    }
}

And assuming you're using asp.net core you need to register it with the IServiceCollection inside the ConfigureServices() method in Startup.cs.

services.AddTransient<IAmbientDbContextLocator, AmbientDbContextLocator>();
services.AddTransient<IDbContextScopeFactory, DbContextScopeFactory>();
services.AddTransient<IDbContextFactory, MagicDbContextFactory>(); 

And then you setup your dbcontext per normal in the Startup.cs

services.AddDbContext<MyDbContext>(options =>
{
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});

kemmis avatar Aug 03 '17 18:08 kemmis

@kemmis,

I followed your example, but I had an issue that occurred when two factories were called during one api request.

I fixed it by specifying a lifetime option for the DbContext like this:

services.AddDbContext<MyDataContext>(options =>
            {
                options.UseSqlServer(connString);
            }, ServiceLifetime.Transient);

dbraynard avatar Nov 03 '17 20:11 dbraynard