具有这两个实体后,我将它们获取,然后将它们传递到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'来查看冲突的键值。“
问题-我没有正确更新子实体还是其他东西?