question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Multiple database providers in service provider exception when trying to use InMemoryDatabase for unit testing.

See original GitHub issue

I don’t really know if I should ask this here but I can’t find information about this issue anywhere else. I can not seem to get started with xUnit using an EF’s InMemory database. Basically since I don’t want to mess up anything in my SqlServer database I try to create an InMemory database using Microsoft.EntityFrameworkCore.InMemory package like so:

private ZvezdichkaDbContext GetDatabase()
{
            var dbOptions = new DbContextOptionsBuilder<MyDbContext>()
                .UseInMemoryDatabase(Guid.NewGuid().ToString())
                .Options;

            return new ZvezdichkaDbContext (dbOptions);
}

[Fact]
        public void JustTest()
        {
            //Arrange
            var db = GetDatabase();

            var p1 = new Product()
            {
                Description = "Qko",
                Name = "First",
                Price = 12.12m,
                Stock = 15
            };

            var p2 = new Product()
            {
                Description = "Qko2",
                Name = "Second",
                Price = 8.99m,
                Stock = 10
            };

            db.AddRange(p1, p2);
           var products = new ProductsDataService(db);
           //exception thrown here

            //Act
            //Assert
        }

So far so good. When I try to make a new ProductsDataService with this context it throws the following error:

Exception message:
Message: System.InvalidOperationException : Services for database providers 'Microsoft.EntityFrameworkCore.InMemory', 'Microsoft.EntityFrameworkCore.SqlServer' have been registered in the service provider. Only a single database provider can be registered in a service provider. If possible, ensure that Entity Framework is managing its service provider by removing the call to UseInternalServiceProvider. Otherwise, consider conditionally registering the database provider, or maintaining one service provider per database provider.

Stack trace:	
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityStates(IEnumerable`1 entities, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.AddRange(IEnumerable`1 entities)
   at Microsoft.EntityFrameworkCore.DbContext.AddRange(Object[] entities)
   at Zvezdichka.Tests.ProductsDataServiceTests.JustTest() in D:\Github\Zvezdichka-Store\Zvezdichka.Tests\ProductsDataServiceTests.cs:line 40

Steps to reproduce

My ProductsDataService receives the DbContext from the ASP NET Core DI container. The data service implements a GenericDataService<T>. All data services are registered as transient in the services provider.

public abstract class GenericDataService<T> : IGenericDataService<T> where T : class
    {
        protected DbSet<T> _dbSet;

        protected GenericDataService(ZvezdichkaDbContext dbContext)
        {
            this._dbSet = dbContext.Set<T>();
        }

//some common methods for all data services
}

public class ProductsDataService : GenericDataService<Product>, IProductsDataService
    {
        public ProductsDataService(ZvezdichkaDbContext dbContext) : base(dbContext)
        {
        }
    }

In Startup.cs

 public void ConfigureServices(IServiceCollection services)
{
            services.AddDbContext<ZvezdichkaDbContext>(options =>
                options.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection")));

//some code
}

I’ve tried anything but can’t find a solution. If someone could please give me a hand that would be massive!

Further technical details

EF Core version: (found in project.csproj or packages.config) Database Provider: (e.g. Microsoft.EntityFrameworkCore.SqlServer) Operating system: IDE: (e.g. Visual Studio 2017 15.4)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

23reactions
smitpatelcommented, Apr 23, 2020

To add more, if you want to use multiple providers with same DbContext then passing DbContextOptions through parameter is appropriate way. Since each provider specific context can send in correct options. OnConfiguring is not exclusive to ctor options and hence it will be also run even if options passed into ctor is already configured. If you must have OnConfiguring method to configure one of the providers then you can make it conditional like this

protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
    if (!builder.IsConfigured)
    {
        builder.UseSqlServer(...);
    }
}
12reactions
slupovcommented, Dec 19, 2017

Removed the OnConfiguring method in the DbContext and the problem was solved.

protected override void OnConfiguring(DbContextOptionsBuilder builder)
        {
            builder.UseSqlServer(ConnectionString);
            base.OnConfiguring(builder);
        }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Multiple DB providers error in integration tests in ASP.NET ...
The error indicates you've create a dbcontext with two database providers. Since you've replaced DbContextOptions in IServiceCollection with ...
Read more >
Avoid In-Memory Databases for Tests
A controversial GitHub issue came to my attention a couple of weeks ago around ditching the in-memory provider for Entity Framework Core.
Read more >
Entity Framework Core In Memory Testing - Scott Brady
Entity Framework Core testing of relational and non-releational databases using in-memory database providers.
Read more >
Using Entity Framework Core in-memory database for unit ...
In-memory database is non-persistent implementation of data provider that we can use when testing Entity Framework related code. As it doesnät ...
Read more >
Breaking changes in EF Core 6.0
New behavior. Attempting to use this model will now throw the following exception: System.InvalidOperationException: Entity type 'ContactInfo' ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found