无法使用实体框架核心更新控制器中的子实体

时间:2020-01-24 10:25:17

标签: c# entity-framework entity-framework-core

具有这两个实体后,我将它们获取,然后将它们传递到UI之前将它们映射到viwemodels / dtos。 我还必须忽略startup.cs文件中的引用循环处理,以将其正确映射到DTO。

public class Matter
{
    public int Id { get; set; }
    public ICollection<MatterExposure> Exposures { get; set; }
    // other properties
}
public class MatterExposure
{
     public int Id { get; set; }
     public Matter Matter { get; set; }
     // other properties
}

当我在UI中保存表单(包括'MatterExposure's表)时,我会将所有内容传递回控制器以进行保存。 信息-尚未在下面的控制器调用中保存子实体“ MatterExposure”,并且效果很好!

[HttpPut("{id}")]
public async Task<IActionResult> UpdateData(string id, MatterForClaimDetailedDto generalMatterDto)
{
    var user = await _userManager.GetUserAsync(HttpContext.User);
    var matter = await _autoRepo.GetMatter(id);
    // fill some matter data and add a child then save and it works fine 
    if (await _autoRepo.SaveAll())
            return NoContent(); 
}
public class MatterForClaimDetailedDto
{
    public int Id { get; set; }
    public GeneralMatterDto MatterData { get; set; }
    public ICollection<MatterExposure> Exposures { get; set; }
    // other properties
}

现在,我想添加MatterExposure实体的更新,因为我可以在UI中对其进行更改。所以我尝试像这样使用UpdateRange

[HttpPut("{id}")]
public async Task<IActionResult> UpdateData(string id, MatterForClaimDetailedDto generalMatterDto)
{
    var user = await _userManager.GetUserAsync(HttpContext.User);
    var matter = await _autoRepo.GetMatter(id);
    matter.EditedDate = DateTime.Now;
    matter.FirstName = generalMatterDto.FirstName;
    matter.LastName = generalMatterDto.LastName;

    _autoRepo.UpdateRange<List<MatterExposure>>(generalMatterDto.Exposures.ToList());
    await _autoRepo.SaveAll()
}
public void UpdateRange<T>(T entity) where T : class
{
    _autoContext.UpdateRange(entity);
}

但是在调用UpdateRange时,出现以下异常消息:

“未找到实体类型'List MatterExposure'。确保已将实体类型添加到模型中。“

就我而言,我有这个:

public DbSet<MatterExposure> MatterExposure { get; set; }

然后我在下面没有运气尝试了

public DbSet<List<MatterExposure>> MatterExposure { get; set; }

我想我会尝试更新每个单独的“ MatterExposure”实体,以查看是否会改变任何内容。因此,我尝试删除UpdateRange调用,并尝试使用单个的“ MatterExposure”实体

  foreach(var exposure in generalMatterDto.Exposures) {
      _autoRepo.Update<MatterExposure>(exposure);
   }
   // in my repo I have this with different things I tried
   public void Update<T>(T entity) where T : class
    {
        // _autoContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        //_autoContext.Entry(entity).State = EntityState.Detached;
        _autoContext.Update(entity);
       // _autoContext.ChangeTracker.
    }

在通过每个对仓库的“ MatterExposure”更新调用的第一个循环中,我得到了这个异常

“无法跟踪实体类型'MatterExposure'的实例,因为已经跟踪了另一个具有相同的{'Id'}键值的实例。在附加现有实体时,请确保只有一个具有给定键值的实体实例已附加。请考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'查看冲突的键值。“

在上面的异常之后,我尝试将循环放在控制器方法的顶部,以查看其他实体是否在干扰。

// at top of controler method before the other entity actions are performed
foreach(var exposure in generalMatterDto.Exposures) {
    _autoRepo.Update<MatterExposure>(exposure);
}

然后将for循环移到控制器的顶部,在第一次迭代中运行,但是在第二次迭代中失败,再次给我同样的错误消息

“无法跟踪实体类型'MatterExposure'的实例,因为 具有{'Id'}相同键值的另一个实例已经被跟踪。 附加现有实体时,请确保仅附加一个具有给定键值的实体实例。 考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'来查看冲突的键值。“

问题-我没有正确更新子实体还是其他东西?

0 个答案:

没有答案