Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core and UseInMemoryDatabase

I am trying to write a tests using Entity Framework Core UseInMemoryDatabase so my setup looks like:

    [SetUp]
    public void Setup()
    {
        this.ContextOptions = new DbContextOptionsBuilder<GeneralContext>()
            .UseInMemoryDatabase(databaseName: "DiagAc2Tests")
            .Options;
    }

I dont know if it is needed, but context looks like:

public class GeneralContext : DbContext
{
    public DbSet<Entities.Application> Applications { get; set; }
    public GeneralContext() { }
    public GeneralContext(DbContextOptions<GeneralContext> options) : base(options) { }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var config = new DatabaseConfiguration();
        optionsBuilder.UseNpgsql(config.GetConnectionString());
    }
}

I use this context through out my application and it works, so my test looks like:

        public async Task CreateApplicationByService()
        {
            Mock<DTO.IApplication> mock = new Mock<DTO.IApplication>();
            mock.SetupProperty(f => f.Name, "Application");
            mock.SetupProperty(f => f.ProjectId, 666);
            mock.SetupProperty(f => f.ConfigFilePath, null);

            DTO.IApplication appDto = mock.Object;

            var entity = this.Mapper.Map<DTO.IApplication, Application>(appDto);
            try
            {
                using var context = new GeneralContext(this.ContextOptions);
                await context .ApplicationRepository.Add(entity);
            }
            catch (Exception ex)
            {
                var t = ex;
            }

            var one = 1;
            var two = 2;
            Assert.True(one != two);
        }

I dont have any asserts, thats why that silly assert is added, yet but when I add record through context I am getting:

Services for database providers 'Microsoft.EntityFrameworkCore.InMemory', 'Npgsql.EntityFrameworkCore.PostgreSQL' 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.

I done everything according to documentation on MSDN, so waht could be wrong?

like image 937
Wojciech Szabowicz Avatar asked Jan 25 '26 04:01

Wojciech Szabowicz


1 Answers

optionsBuilder.UseNpgsql(config.GetConnectionString());

The mistake is in this line and this an example of inversion of control. You should not call UseNpqSql within OnConfiguring. What this does is that it tried to use 2 databases.

this.ContextOptions = new DbContextOptionsBuilder<GeneralContext>()
        .UseInMemoryDatabase(databaseName: "DiagAc2Tests")
        .Options;

optionsBuilder.UseNpgsql(config.GetConnectionString());

Both of the above statements will be run.

Now the solution to this is to move UseNpgsql outside of configuring and in your app startup class. That of course depends on your project and how you want to achieve it.

like image 188
A_kat Avatar answered Jan 28 '26 07:01

A_kat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!