检查当前上下文中是否已存在 EF 实体

FaN*_*NIX 3 c# ef-code-first entity-framework-6

我知道已经有几个关于此的问题,但没有一个真正解决我的问题:

应用背景

我有一个首先使用 Entity Framework 6.1 Code 的 Web 应用程序。我在 DAL 中使用存储库模式,这意味着我有存储库来查询我的上下文并将结果返回到服务,然后服务使用自动映射器将我的实体映射到视图模型,然后返回虚拟机。服务通过 Web API 方法调用。

基于上述架构,很明显我正在使用独立的实体。

我遇到的问题是更新(PUT)现有实体。流程如下所示:

Angular 向 WebAPI 方法发出 HTTP PUT,将 VM 作为参数传递。然后,WebAPI 调用 Service 方法,并将 VM 作为参数传递。服务方法使用自动映射器将 VM 转换为 EF 实体 服务方法然后调用相应的存储库,将分离的 EF 实体的新实例作为参数传递。

服务方法示例:

    public async Task<List<DependantViewModel>> SaveDependants(int customerId, List<DependantViewModel> dependantViewModels)
    {
        var dependantEntities = Mapper.Map<List<DependantViewModel>, List<Dependant>>(dependantViewModels);

        bool result = false;
        foreach (var dependantEntity in dependantEntities)
        {
            result = await _dependantRepository.InsertOrUpdate(dependantEntity);
            if (result != true)
            {
                // log errror
            }
        }

        return Mapper.Map<List<Dependant>, List<DependantViewModel>>(dependantEntities);
    }
Run Code Online (Sandbox Code Playgroud)

基础仓库:

    public virtual async Task<bool> InsertOrUpdate(TE entity)
    {
        if (entity.Id == 0 || entity.Id == ModelState.New)
        {
            // insert new item
            _context.Entry<TE>(entity).State = EntityState.Added;
        }
        else
        {
            // update existing item
            _context.Entry<TE>(entity).State = EntityState.Modified;
            _context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
            _context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
        }
        return await _context.SaveChangesAsync() > 0;
    }
Run Code Online (Sandbox Code Playgroud)

尝试设置时发生异常:

_context.Entry(entity).State = EntityState.Modified;

附加“Business.Data.Entities.Customer.Dependant”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图表中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。

据我了解,发生这种情况是因为在设置实体状态之前需要先附加分离的实体。问题是,我无法附加实体,因为它已经在 context.Dependant.local 集合中。由于某种原因,实体框架已经在跟踪实体。

有没有办法首先检查上下文中是否存在实体,如果不存在,则附加,否则,检索已附加的实体,并将修改后的实体的更改应用到附加的实体(如果有意义) 。

感谢任何反馈

FaN*_*NIX 5

这对我有用:

public virtual async Task<bool> InsertOrUpdate(TE entity)
{
    if (entity.Id == 0 || entity.Id == ModelState.New)
    {
        // insert new item
        _context.Entry<TE>(entity).State = EntityState.Added;
    }
    else
    {           
        var attachedEntity = _context.ChangeTracker.Entries<TE>().FirstOrDefault(e => e.Entity.Id == entity.Id);
        if (attachedEntity != null)
        {
            // the entity you want to update is already attached, we need to detach it and attach the updated entity instead
            _context.Entry<TE>(attachedEntity.Entity).State = EntityState.Detached;
        }

        _context.Entry<TE>(entity).State = EntityState.Modified; // Attach entity, and set State to Modified.
        _context.Entry<TE>(entity).Property(o => o.CreatedUserId).IsModified = false;
        _context.Entry<TE>(entity).Property(o => o.CreatedDate).IsModified = false;
    }
    return await _context.SaveChangesAsync() > 0;
}
Run Code Online (Sandbox Code Playgroud)