1

I have this code but I can't get it to work together, if I comment the first 4 lines of code if I update the address,and if I comment on the code to update the address, it no longer updates the 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();
}

this part:

  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;

no longer allows me to update what is below:

 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;
        }
    }

error:

Error AutoMapper.AutoMapperMappingException: Error mapping types. Mapping types: Cliente -> Cliente BlazorApp.Shared.Models.Cliente -> BlazorApp.Shared.Models.Cliente Type Map configuration: Cliente -> Cliente BlazorApp.Shared.Models.Cliente -> BlazorApp.Shared.Models.Cliente Destination Member: ClienteTipodeConcepto ---> System.InvalidOperationException: The instance of entity type 'Direccion' cannot be tracked because another instance with the same key value for {'DireccionId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using

How can I make the whole form update fine?

1

2 Answers 2

2

Here you have and entity tracked by the context (found by matching ClienteId):

var clienteDB = await context.Clientes.FirstOrDefaultAsync(x => x.ClienteId == cliente.ClienteId);

This statement updates the tracked entity with cliente (this would set clienteDB state to EntityState.Modified):

clienteDB = mapper.Map(cliente, clienteDB);

Then you try to get the context to track the original item cliente with the same Id in the context.

context.Entry(cliente).State = EntityState.Modified;

You cannot have two instances tracking the same entity. I would remove this line and adjust the rest of your code to work with clienteDB.

Sign up to request clarification or add additional context in comments.

Comments

0

Firstly you just need to convert the object that you are passing as an input to the corresponding object model declared in dbcontext:

var clienteDB = mapper.Map<object model declared in ef>(cliente);

Then if you want to have a control if this record already exists:

var clienteDB = await context.Clientes.FindAsync(cliente.ClienteId);
    if (clienteDB == null) { return NotFound(); }

and then iterate each element from the object corresponding to the context:

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;
    }
}

3 Comments

I get a map error if I only pass the cliente, map expects the source and destination
yes but the automapper it's generic so you can set it mapper.map<Your object model in dbcontext>(cliente)
@Enrique, it seems here one could also use context.Clients.Update(cliente) instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.