如何使用Entity Framework Core在一個方法中保存兩次更改

entity-framework entity-framework-6 entity-framework-core

使用Entity Framework Core我試圖為同一個實體集合保存兩次更改。

    public async Task Save(IEnumerable<Request> request)
    {            
        var entities = request.Select(x => new MyEntity()
        {
            FileName = x.FileName,                
            Status = Status.Downloading                
        });

        // save as downloading
        await _dbContext.MyFiles.AddRangeAsync(entities).ConfigureAwait(false);
        await _dbContext.SaveChangesAsync().ConfigureAwait(false);

        // start downloading
        await _storage.DownloadFilesAsync(request).ConfigureAwait(false);

        // save as downloaded
        foreach (var entity in entities)
        {
            entity.Status = Status.Downloaded;
        }

        // this save DOES NOT update the entities with status Downloaded
        await _dbContext.SaveChangesAsync().ConfigureAwait(false);          
    }

第一次調用SaveChanges()方法在DB中創建狀態為Downloading實體。

然後我將實體的狀態修改為Downloaded並再次調用SaveChanges() 。但是,這次實體不會在DB中更新。

我認為實體已經加載在Db上下文中,所以我不必在第二次SaveChanges之前重新加載它們。只修改屬性會標記它們被修改。但它不起作用。

更新1
我更新瞭如下代碼並明確將State設置為Modified

 // save as downloaded
 foreach (var entity in entities)
 {
    entity.Status = Status.Downloaded;      

    // The exception occurs at line below on 2nd loop
   _dbContext.Entry(entity).State = EntityState.Modified;
 }

現在我得到例外

System.InvalidOperationException:無法跟踪實體類型“MyEntity”的實例,因為已經跟踪了具有相同鍵的此類型的另一個實例。添加新實體時,對於大多數鍵類型,如果未設置任何鍵,則將創建唯一的臨時鍵值(即,如果為鍵屬性指定了其類型的默認值)。如果要為新實體顯式設置鍵值,請確保它們不會與現有實體或為其他新實體生成的臨時值發生衝突。附加現有實體時,請確保只有一個具有給定鍵值的實體實例附加到上下文。在Microsoft.EntityFrameworkCore.ChangeTracking.InternalEntityEntry.SetEntityState中的Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry條目)中的Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key,InternalEntityEntry條目) EntityState oldState,EntityState newState,Boolean acceptChanges)

實體具有Id屬性的類型int和該Id屬性也有[Key]屬性。

public class MyEntity
{
   [System.ComponentModel.DataAnnotations.Key]
   public int Id {get;set;}
   public string FileName {get;set;}
   public string Status {get;set;}
}

更新2
因此,在進行了一些調試後,我發現第一個SaveChanges()操作是在數據庫中創建記錄,並按預期為每個記錄分配唯一的ID。 Id是數據庫中自動遞增的標識列。但是,實體不會使用新的ID刷新。所以所有實體在第一次保存更改後仍然具有值0。

如何使用新創建的ID刷新這些實體?

foreach循環中,我嘗試重新加載

   _dbContext.Entry<OcrFile>(entity).ReloadAsync().ConfigureAwait(false);

但那並沒有刷新。

熱門答案

解決!!。在將它們傳遞給AddRange方法之前,我必須急切地使用ToList()ToArray()加載實體

    var entities = request.Select(x => new MyEntity()
    {
        FileName = x.FileName,                
        Status = Status.Downloading                
    }).ToList();

我不確定這是EF中的錯誤但我為該問題創建了一個單獨的SO線程



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow