我正在使用内存数据库提供程序进行集成测试,但我似乎无法更新记录。我对一个真正的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错误。我确信有人会注意到你无法更新的数据库。
答案 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;