aspnetboilerplate - 为什么这会引发 PK 重复错误?
问题描述
这是我的测试用例,我希望它是自我解释的。
[Fact]
public async Task ShouldAllowEntityUpdate()
{
var _tenantRepo = LocalIocManager.Resolve<IRepository<Tenant>>();
Tenant tenant = _tenantRepo.Insert(new Tenant("Tname", "name"));
var _userRepo = LocalIocManager.Resolve<IRepository<User,long>>();
_userRepo.Insert(new User()
{
Tenant = tenant,
Name = "jojo"
});
}
这会引发错误,因为它在_userRepo.Insert
. 这应该由 EF 跟踪,因此知道它是一个现有的实体?
快速回购的副本在这里: https ://github.com/Worthy7/AspAbpSpa/commit/d40f238480934a472a122d6ca6f5cda7ed8e21cd
Test Name: AspAbpSPAMay.Tests.PkDupBug.ShouldAllowEntityUpdate
Test FullName: AspAbpSPAMay.Tests.PkDupBug.ShouldAllowEntityUpdate
Test Source: C:\Users\Ian\Source\Repos\AspAbpSPAMay\4.6.0\test\AspAbpSPAMay.Tests\PkDupBug.cs : line 13
Test Outcome: Failed
Test Duration: 0:00:04.126
Result StackTrace:
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at Microsoft.EntityFrameworkCore.InMemory.Storage.Internal.InMemoryTable`1.Create(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.InMemory.Storage.Internal.InMemoryStore.ExecuteTransaction(IReadOnlyList`1 entries, IDiagnosticsLogger`1 updateLogger)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Abp.EntityFrameworkCore.AbpDbContext.SaveChanges() in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\AbpDbContext.cs:line 208
at Abp.Zero.EntityFrameworkCore.AbpZeroCommonDbContext`3.SaveChanges() in D:\Github\aspnetboilerplate\src\Abp.ZeroCore.EntityFrameworkCore\Zero\EntityFrameworkCore\AbpZeroCommonDbContext.cs:line 159
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesInDbContext(DbContext dbContext) in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 163
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChanges() in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 60
at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.CompleteUow() in D:\Github\aspnetboilerplate\src\Abp.EntityFrameworkCore\EntityFrameworkCore\Uow\EfCoreUnitOfWork.cs:line 77
at Abp.Domain.Uow.UnitOfWorkBase.Complete() in D:\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkBase.cs:line 256
at Abp.Domain.Uow.UnitOfWorkInterceptor.PerformSyncUow(IInvocation invocation, UnitOfWorkOptions options) in D:\Github\aspnetboilerplate\src\Abp\Domain\Uow\UnitOfWorkInterceptor.cs:line 68
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.IRepository`2Proxy_4.InsertOrUpdate(User entity)
at AspAbpSPAMay.Tests.PkDupBug.ShouldAllowEntityUpdate() in C:\Users\Ian\Source\Repos\AspAbpSPAMay\4.6.0\test\AspAbpSPAMay.Tests\PkDupBug.cs:line 23
--- End of stack trace from previous location where exception was thrown ---
Result Message: System.ArgumentException : An item with the same key has already been added. Key: 2
如果这是错误的方法,那么正确的方法是什么?
查看其他问题的答案,似乎我的租户实体由于某种原因而分离。是因为它需要在 UOW 中才能继续跟踪吗?
解决方案
正确版本:
[Fact]
public async Task ShouldAllowEntityUpdate()
{
var unitOfWorkManager = Resolve<IUnitOfWorkManager>();
var _tenantRepo = LocalIocManager.Resolve<IRepository<Tenant>>();
Tenant tenant = _tenantRepo.Insert(new Tenant("Tname", "name"));
//COMMIT CHANGES to GET the new tenant's Id
_unitOfWorkManager.Current.SaveChanges();
var _userRepo = LocalIocManager.Resolve<IRepository<User,long>>();
//Use TenantId to set the tenant.
_userRepo.Insert(new User()
{
TenantId = tenant.Id,
Name = "jojo"
});
}
推荐阅读
- tsql - Power Automate - 执行存储过程 (V2) - 始终返回 HTTP 错误 400
- javascript - 尝试使用 jquery 和会话 cookie 创建一个记住我的功能,但应用程序在再次运行时甚至不会加载
- r - 如何使用“是”或“否”重命名逻辑值(TRUE 或 FALSE)并将 distinct() 应用于 FALSE 值
- javascript - 使 chrome 扩展能够查询浏览器页面的窗口
- macos - Spotlight 货币转换器未更新
- dafny - 断言和集合基数
- html - HTML5画布可动线
- swift - CGContext.draw(), CGContext.makeImage() 给我双倍的预期分辨率
- android-studio - 在 Android Studio 中配置导入顺序?
- javascript - 如何在client.js中访问登录表单的输入标签值(名称)