[英]Why does Entity Framework show that item is already tracked, despite of fact that it is not tracked?
我有 3 個測試,在每個測試之間,都會創建一個新的DbContext
。 我檢查了它只是運行了 3 個測試用例,都將相同的 object 添加到 db 並且沒有錯誤。 但是當我運行這個測試時:
[TestCase("test2@test.com", "test2@test.com", "123", "321", UserSaveResultStatus.UserAlreadyExists, Description = "Duplicated emails")]
[TestCase("test3@test.com", "test4@test.com", "456", "456", UserSaveResultStatus.UserWithGivenEmployeeIdAlreadyExists, Description = "Duplicated Employee Ids")]
[TestCase("test5@test.com", "test6@test.com", "", "", UserSaveResultStatus.Success, Description = "Empty Employee Ids. Should add two users")]
public void ImportUsers_Should_Add_User_Only_Once_When_Email_Or_EmployeeId_Doubled_On_The_List(string email1, string email2, string employeeId1, string employeeId2, UserSaveResultStatus expectedStatus)
{
var emails = new string[] { email1, email2 };
var employeeIds = new string[] { employeeId1, employeeId2 };
var dto = GetUserImportDto(emails, employeeIds);
var checker = dbContext.ChangeTracker
.Entries()
.Where(t => t.State == EntityState.Detached
|| t.State == EntityState.Unchanged
|| t.State == EntityState.Modified
|| t.State == EntityState.Detached
|| t.State == EntityState.Deleted
|| t.State == EntityState.Added);
.
.
.
Asserts
我收到此錯誤:
無法跟蹤實體類型“PowerPlantUser”的實例,因為已經在跟蹤具有相同鍵值 {'Id'} 的另一個實例。 附加現有實體時,請確保僅附加一個具有給定鍵值的實體實例。 考慮使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”來查看沖突的鍵值
拋出錯誤時,我在適當的位置創建斷點:
foreach (var powerPlantId in newPowerPlantsIds)
{
var personToAdd = new PowerPlantUser() { UserId = userId, PowerPlantId = powerPlantId };
var state1 = commandsContext.Entry(personToAdd).State;
var state2 = commandsContext.Entry(personToAdd).State; //STATE BEFORE ERROR IS DETACHED
commandsContext.PowerPlantUsers.Add(personToAdd); //HERE IS AN ERROR
正如我們在上面的測試中看到的那樣,我創建了檢查器,它顯示了跟蹤的條目。 新 PowerPlantUser 的 id = 0 並且檢查器中沒有此用戶。
當我單獨運行測試時,沒有錯誤並且所有測試都通過了。 誰能告訴我問題出在哪里?
該錯誤意味着 DbContext 已跟蹤具有相同 ID 的 PowerPlantUser 的不同實例。 它還指的是“Id”列,因此當您提供 UserId 和 PowerPlantId 時,我會檢查您是否正在實現一些基本 class 或定義一個未正確設置的常見“Id”列一個標識,導致每條記錄可能以“0”的 PK 進入數據庫。
檢查您的 PowerPlantUser 定義的 Id 列以及它是否正確設置為 Identity 列。 (也可以取決於您用於測試的數據庫。)
檢查本地跟蹤緩存以查找匹配實體。 如果 PK 肯定是 PowerPlantId + UserId,則添加以下代碼以確認 Context 是否正在跟蹤現有實體:
..
var existingItem = commandsContext.PowerPlantUsers.Local
.SingleOrDefault(x => x.PowerPlantId == powerPlantId && x.UserId == userId);
這會檢查 DbContext 的跟蹤緩存。 如果它返回一個實體,那么其他東西會在 DbContext 中插入和留下一個跟蹤的實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.