如何在同一测试中更新最近添加的实体实例?

How can you update a recently added instance of an entity in the same test?

这是我的问题。我想在实现简单更新的控制器中测试一个函数。 我有错误代码:

The instance of entity type 'Data' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked.

在我的例子中,Data.Id 是主键。

如何将数据放入 "database" 之前,而不发生此错误? 我的假设是我之前输入的数据将被跟踪并在 "tracked state" 中,因此无法更新。

这个想法是为了测试一切都在 UpdateData 中运行并执行更新。 新数据中唯一发生变化的是新的 "Data.Title",例如字符串数据类型。

我尝试更改 "testData" 的 EntityState,但这没有帮助。 我已经搜索并尝试了很多,但我不知所措。

执行 "db.Data.Update(data)" 时 UpdateData() 函数发生错误。

这是我编写的程序:

控制器:

public async Task<IActionResult> UpdateData(DataDto dataDto){
        var data = mapper.Map<Data>(dataDto);
        //some updating happens here
        db.Data.Update(data);
        wait db.SaveChangesAsync();
        return Ok();
}

辅助函数:

public static ApplicationDbContext DbContext(){
        var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
           .UseInMemoryDatabase(Guid.NewGuid().ToString())
           .Options;

        var context = new ApplicationDbContext(options);
        return context;
}

测试函数:

[Fact]
public async void UpdateDataTest(){
        //here happens some Mapper initialization
        await using var context = HelperFunction.DbContext();
        await context.Data.AddAsync(testData);
        await context.SaveChangesAsync();
        var dataController = new DataController(context, mapper){};
        var result = await dataController.UpdateData(changedTestData);
        // do some UnitTest

}

您可以 create/recreate 为 DataController 新建 DbContext,如下所示:

[Fact]
public async void UpdateDataTest(){
        //here happens some Mapper initialization
        var contextId = Guid.NewGuid();
        await using (var context = HelperFunction.DbContext(contextId))
        {
            await context.Data.AddAsync(testData);
            await context.SaveChangesAsync();
        }
        await using var contextForController = HelperFunction.DbContext(contextId);
        var dataController = new DataController(contextForController, mapper){};
        var result = await dataController.UpdateData(changedTestData);
        // do some UnitTest    
}

您还需要更新 HelperFunction.DbContext 以便它可以接受 Guid 或仅接受一些字符串标识符以便它访问相同的内存数据库范围:

public static ApplicationDbContext DbContext(Guid? guid = null){
        var options = new DbContextOptionsBuilder<ApplicaitonDbContext>
           .UseInMemoryDatabase((guid ?? Guid.NewGuid()).ToString())
           .Options;

        var context = new ApplicationDbContext(options);
        return context;
}