我正在使用内存数据库提供程序进行集成测试,但是我似乎无法更新记录。我已经对一个真正的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错误。我确定有人会注意到您无法更新的数据库。
事实证明,将测试夹具中DbContext的生存期更改为单例可以解决我的问题。
可能是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
}
添加到克里斯的答案。这是我所遇到的问题与解决此问题的示例:
services.AddDbContext<TestDbContext>(options => {
options.UseInMemoryDatabase("TestDb");
});
to
var options = new DbContextOptionsBuilder<TestDbContext>()
.UseInMemoryDatabase(databaseName: "TestDb")
.Options;
services.AddSingleton(x => new TestDbContext(options));