簡體   English   中英

為什么實體框架顯示該項目已被跟蹤,盡管它沒有被跟蹤?

[英]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 進入數據庫。

  1. 檢查您的 PowerPlantUser 定義的 Id 列以及它是否正確設置為 Identity 列。 (也可以取決於您用於測試的數據庫。)

  2. 檢查本地跟蹤緩存以查找匹配實體。 如果 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM