实体框架核心和UseInMemoryDatabase

时间:2020-01-24 11:02:46

标签: .net-core entity-framework-core

我正在尝试使用Entity Framework Core UseInMemoryDatabase编写测试,因此我的设置如下:

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

我不知道是否需要它,但是上下文看起来像:

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());
    }
}

我在整个应用程序中都使用了此上下文,并且可以正常工作,因此我的测试如下:

        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);
        }

我没有任何断言,这就是为什么要添加那个愚蠢的断言,但是当我通过上下文添加记录时,我得到了:

数据库提供者的服务'Microsoft.EntityFrameworkCore.InMemory','Npgsql.EntityFrameworkCore.PostgreSQL'已在服务提供者中注册。在服务提供商中只能注册一个数据库提供商。如果可能,请通过删除对UseInternalServiceProvider的调用来确保Entity Framework正在管理其服务提供商。否则,请考虑有条件地注册数据库提供者,或为每个数据库提供者维护一个服务提供者。

我已经按照MSDN上的文档进行了所有操作,所以这可能是错误的?

2 个答案:

答案 0 :(得分:3)

optionsBuilder.UseNpgsql(config.GetConnectionString());

错误在这一行,这是控制反转的一个例子。您不应该在UseNpqSql中调用OnConfiguring.,这是因为它试图使用2个数据库。

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

optionsBuilder.UseNpgsql(config.GetConnectionString());

以上两个语句都将运行。

现在的解决方案是将UseNpgsql移出配置之外,并移至应用程序启动类中。那当然取决于您的项目以及您如何实现它。

答案 1 :(得分:0)

在测试项目中,可以使用与应用程序不同的单独的Startup类,并且可以从内存中数据库中删除UseNpgsql。