如何使用Entity Framework Core

时间:2017-03-30 21:55:41

标签: 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()方法会在数据库中创建状态为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”,因为此类型的另一个实例   已经跟踪了相同的密钥。添加新实体时,   对于大多数密钥类型,如果不是,将创建唯一的临时密钥值   key被设置(即,如果为key属性分配了默认值   它的类型)。如果您明确设置新实体的键值,   确保它们不会与现有实体或临时值发生冲突   为其他新实体生成。附加现有实体时,   确保只有一个具有给定键值的实体实例   附在上下文中。在   Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKEY的   key,InternalEntityEntry条目)at   Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry   进入)   Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(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);

但是没有刷新。

1 个答案:

答案 0 :(得分:1)

解决!!。我必须先使用ToList()ToArray()加载实体,然后再将其传递给AddRange方法

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

我不确定这是EF中的错误但我为该问题创建了单独的SO thread