我有这个代码,但我无法让它一起工作,如果我在更新地址时注释前4行代码,如果我对代码进行注释以更新地址,它将不再更新ClienteTipodeConcepto。
[HttpPut]
public async Task<ActionResult> Put(Cliente cliente)
{
var clienteDB = await context.Clientes.FirstOrDefaultAsync(x => x.ClienteId == cliente.ClienteId);
if (clienteDB == null) { return NotFound(); }
clienteDB = mapper.Map(cliente, clienteDB);
clienteDB.ClienteTipodeConcepto = cliente.ClienteTipodeConcepto;
context.Entry(cliente).State = EntityState.Modified;
foreach (var direccion in cliente.Direccion)
{
if (direccion.DireccionId != null)
{
context.Entry(direccion).State = EntityState.Modified;
}
else
{
context.Entry(direccion).State = EntityState.Added;
}
}
var listadoDireccionesIds = cliente.Direccion.Select(x => x.DireccionId).ToList();
var direccionesABorrar = await context
.Direcciones
.Where(x => !listadoDireccionesIds.Contains(x.DireccionId) && x.Cliente.ClienteId == cliente.ClienteId)
.ToListAsync();
context.RemoveRange(direccionesABorrar);
await context.SaveChangesAsync();
return NoContent();
}
这部分:
var clienteDB = await context.Clientes.FirstOrDefaultAsync(x => x.ClienteId == cliente.ClienteId);
if (clienteDB == null) { return NotFound(); }
clienteDB = mapper.Map(cliente, clienteDB);
clienteDB.ClienteTipodeConcepto = cliente.ClienteTipodeConcepto;
不再允许我更新以下内容:
context.Entry(cliente).State = EntityState.Modified;
foreach (var direccion in cliente.Direccion)
{
if (direccion.DireccionId != null)
{
context.Entry(direccion).State = EntityState.Modified;
}
else
{
context.Entry(direccion).State = EntityState.Added;
}
}
错误:
错误AutoMapper.AutoMapperMappingException:错误映射类型。映射类型:Cliente->客户端BlazorApp.Shared.Models.Client->BlazorApp.Shared.Models.ClientType映射配置:Cliente->客户端BlazorApp.Shared.Models.Client->BlazorApp.Shared.Models.Client目标成员:ClienteTipodeConcepto->System.InvalidOperationException:无法跟踪实体类型"Direccion"的实例,因为另一个具有{'DireccionId'}相同键值的实例已被跟踪。附着现有实体时,请确保只有一个实体附加了具有给定键值的实例。考虑使用
如何使整个表单更新良好?
这里有一个由上下文跟踪的实体(通过匹配ClienteId找到(:
var clienteDB = await context.Clientes.FirstOrDefaultAsync(x => x.ClienteId == cliente.ClienteId);
此语句使用cliente
更新被跟踪的实体(这将把clienteDB
状态设置为EntityState.Modified
(:
clienteDB = mapper.Map(cliente, clienteDB);
然后,您尝试获取上下文来跟踪上下文中具有相同Id的原始项cliente
。
context.Entry(cliente).State = EntityState.Modified;
不能有两个实例跟踪同一实体。我会删除这一行,并调整您的代码的其余部分以使用clienteDB
。
首先,您只需要将作为输入传递的对象转换为dbcontext
:中声明的相应对象模型
var clienteDB = mapper.Map<object model declared in ef>(cliente);
然后,如果你想控制这个记录是否已经存在:
var clienteDB = await context.Clientes.FindAsync(cliente.ClienteId);
if (clienteDB == null) { return NotFound(); }
然后从上下文对应的对象中迭代每个元素:
context.Entry(cliente).State = EntityState.Modified;
foreach (var direccion in clienteDB.Direccion)
{
if (direccion.DireccionId != null)
{
context.Entry(direccion).State = EntityState.Modified;
}
else
{
context.Entry(direccion).State = EntityState.Added;
}
}