Entity Framework Core 和 UseInMemoryDatabase

Woj*_*icz 2 entity-framework-core .net-core

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

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

我不知道是否需要,但上下文如下:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我在整个应用程序中使用此上下文并且它有效,所以我的测试如下所示:

        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);
        }
Run Code Online (Sandbox Code Playgroud)

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

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

我按照 MSDN 上的文档完成了所有操作,所以可能有什么问题吗?

Ant*_*dis 6

optionsBuilder.UseNpgsql(config.GetConnectionString());
Run Code Online (Sandbox Code Playgroud)

错误就在这一行,这是控制反转的一个例子。您不应该UseNpqSql在内部调用OnConfiguring.它的作用是尝试使用 2 个数据库。

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

optionsBuilder.UseNpgsql(config.GetConnectionString());
Run Code Online (Sandbox Code Playgroud)

上述两条语句都会运行。

现在解决这个问题的方法是将 UseNpgsql 移到配置之外并移到应用程序启动类中。这当然取决于您的项目以及您想要如何实现它。