EF Core 2.1在内存DB中不更新记录

时间:2018-05-25 14:02:01

标签: entity-framework-core

我正在使用内存数据库提供程序进行集成测试,但我似乎无法更新记录。我对一个真正的SQL数据库运行相同的代码,一切都得到了很好的更新。这是我的测试夹具代码。

测试夹具:

public class TestFixture<TStartup> : IDisposable
{
    private readonly TestServer _testServer;
    public HttpClient TestClient { get; }
    public IDatabaseService DbContext { get { return _testServer.Host.Services.GetService<DatabaseService>(); } }

    public TestFixture() : this(Path.Combine("src")) { }

protected TestFixture(string relativeTargetProjectPatentDir)
{
    Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Testing");

    var builder = new WebHostBuilder()
        .ConfigureServices(services =>
        {
            services.AddDbContext<DatabaseService>(options =>
                options.UseInMemoryDatabase("TestDB")
                .EnableSensitiveDataLogging());
        })
        .UseEnvironment("Testing")
        .UseStartup<Startup>();

    _testServer = new TestServer(builder)
    {
        BaseAddress = new Uri("http://localhost:5010")
    };

    TestClient = _testServer.CreateClient();
    TestClient.BaseAddress = _testServer.BaseAddress;
}

    public void Dispose()
    {
        TestClient.Dispose();
        _testServer.Dispose();
    }
}

我大部分时间都在谷歌上搜索这个并没有遇到任何其他人在谈论它,所以我假设它可能是我的问题而不是EF错误。我确信有人会注意到你无法更新的数据库。

5 个答案:

答案 0 :(得分:1)

原来,将我的测试装置中DbContext的生存期更改为单例可以解决我的问题。

答案 1 :(得分:1)

好吧,DbContext的使用方式有误。我有同样的问题。我以与您相同的方式使用了DbContext。我只是通过.Host.Services.GetService<TContext>返回了实例。这种方法的问题在于DbContext永远不会释放跟踪的实体,因此您可以将实体State设置为EntityState.Detached并强制DbContext重新加载它,否则将使用范围

using (var scope = _testServer.Host.Services.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
  var dbContext = scope.ServiceProvider.GetRequiredService<DatabaseService>();
  //make any operations on dbContext only in scope
}

答案 2 :(得分:1)

更新可以使用Singleton,但我具有CQRS架构,要检查条目是否已在e2e测试中更新,我必须重新加载条目

Context.Entry(entity).Reload();

我希望这可以帮助某人

答案 3 :(得分:0)

添加到克里斯的答案。这是我遇到的问题与解决问题的示例:

services.AddDbContext<TestDbContext>(options => {
 options.UseInMemoryDatabase("TestDb");
});

var options = new DbContextOptionsBuilder<TestDbContext>()
                        .UseInMemoryDatabase(databaseName: "TestDb")
                        .Options;
services.AddSingleton(x => new TestDbContext(options));

答案 4 :(得分:0)

在下面还可以使用AsNoTracking行为

const listName = req.body.list.slice(0,-1); //for removing an extra space

此外,您如何更新记录?似乎可以在EFCore InMemory中进行跟踪,

services.AddDbContext<TestDbContext>(
            a => a.UseInMemoryDatabase(databaseName: "TestDb").UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking),
            ServiceLifetime.Singleton)

但是,这似乎不太有效。

_dbContext.Entry(modifyItem).State = EntityState.Modified;