如何防止 Automapper 替换 Entity Framework 个拥有的实体?
How to prevent Automapper from replacing Entity Framework owned entities?
我有两种类型。位置和位置有一个地址。地址指定为 owned entity 使用
class LocationConfiguration : IEntityTypeConfiguration<Location>
{
public void Configure(EntityTypeBuilder<Location> builder)
{
builder.HasKey(location => new { location.SubscriptionId, location.Id });
builder.OwnsOne(location => location.Address);
}
}
我正在获取现有位置实体并使用 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));
}
我正在通过调用 context.SaveChangesAsync();
进行储蓄
但是我得到了错误
InvalidOperationException: The instance of entity type
'Location.Address#Address' cannot be tracked because another instance
with the key value 'LocationSubscriptionId:123, LocationId:1' is
already being tracked. When replacing owned entities modify the
properties without changing the instance or detach the previous owned
entity entry first.
我怀疑 Automapper 正在替换位置的地址 属性,而不是向下导航并单独替换地址的属性。
有没有办法让 Automapper 对 属性 值进行更精细的复制?
您应该在所有者类型映射配置中配置此类属性 UseDestinationValue
:
UseDestinationValue tells AutoMapper not to create a new object for some member, but to use the existing property of the destination object.
此外,如果您像示例中那样使用自映射,请确保为每个拥有的类型创建显式自映射。
对于您的示例,所需行为的最小 AutoMapper 配置如下:
cfg.CreateMap<Address, Address>();
cfg.CreateMap<Location, Location>()
.ForMember(dest => dest.Address, opt => opt.UseDestinationValue());
我有两种类型。位置和位置有一个地址。地址指定为 owned entity 使用
class LocationConfiguration : IEntityTypeConfiguration<Location>
{
public void Configure(EntityTypeBuilder<Location> builder)
{
builder.HasKey(location => new { location.SubscriptionId, location.Id });
builder.OwnsOne(location => location.Address);
}
}
我正在获取现有位置实体并使用 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));
}
我正在通过调用 context.SaveChangesAsync();
但是我得到了错误
InvalidOperationException: The instance of entity type 'Location.Address#Address' cannot be tracked because another instance with the key value 'LocationSubscriptionId:123, LocationId:1' is already being tracked. When replacing owned entities modify the properties without changing the instance or detach the previous owned entity entry first.
我怀疑 Automapper 正在替换位置的地址 属性,而不是向下导航并单独替换地址的属性。
有没有办法让 Automapper 对 属性 值进行更精细的复制?
您应该在所有者类型映射配置中配置此类属性 UseDestinationValue
:
UseDestinationValue tells AutoMapper not to create a new object for some member, but to use the existing property of the destination object.
此外,如果您像示例中那样使用自映射,请确保为每个拥有的类型创建显式自映射。
对于您的示例,所需行为的最小 AutoMapper 配置如下:
cfg.CreateMap<Address, Address>();
cfg.CreateMap<Location, Location>()
.ForMember(dest => dest.Address, opt => opt.UseDestinationValue());