Ho due tipi. Posizione e posizione ha un indirizzo. L'indirizzo è specificato come entità di proprietà utilizzando
class LocationConfiguration : IEntityTypeConfiguration<Location>
{
public void Configure(EntityTypeBuilder<Location> builder)
{
builder.HasKey(location => new { location.SubscriptionId, location.Id });
builder.OwnsOne(location => location.Address);
}
}
Sto recuperando un'entità Location esistente e mappando valori aggiornati usando Automapper.
[HttpPut("{subscriptionId}/{locationId}")]
public async Task<IActionResult> SaveLocationAsync(string subscriptionId, long locationId, [FromBody] Location location)
{
if (location == null || location.Id != locationId || location.SubscriptionId != subscriptionId)
{
return BadRequest();
}
var dbLocation = await locations.GetLocationAsync(subscriptionId, locationId);
if (dbLocation == null)
{
return NotFound();
}
mapper.Map<Location, Location>(location, dbLocation);
return Ok(await locations.SaveAsync(dbLocation));
}
Sto salvando chiamando context.SaveChangesAsync();
Ma sto ottenendo l'errore
InvalidOperationException: l'istanza del tipo di entità 'Location.Address # Address' non può essere rintracciata perché un'altra istanza con il valore chiave 'LocationSubscriptionId: 123, LocationId: 1' è già stata tracciata. Quando si sostituiscono entità di proprietà, modificare le proprietà senza modificare l'istanza o scollegare per prima la precedente voce dell'entità di proprietà.
Sospetto che Automapper stia sostituendo la proprietà Address della Location piuttosto che navigare verso il basso e sostituire le proprietà dell'indirizzo individualmente.
C'è un modo per fare di Automapper una copia più granulare dei valori delle proprietà?
È necessario configurare tali proprietà nella configurazione del mapping del tipo di proprietario con UseDestinationValue
:
UseDestinationValue dice ad AutoMapper di non creare un nuovo oggetto per alcuni membri, ma di usare la proprietà esistente dell'oggetto di destinazione.
Inoltre, nel caso in cui si stia utilizzando la mappatura automatica come nell'esempio, assicurarsi di creare la mappatura esplicita per ciascun tipo di proprietà.
Per il tuo esempio, la configurazione minima di AutoMapper per il comportamento desiderato è la seguente:
cfg.CreateMap<Address, Address>();
cfg.CreateMap<Location, Location>()
.ForMember(dest => dest.Address, opt => opt.UseDestinationValue());