Как сопоставить два вложенных списка с помощью AutomapperC#

Место общения программистов C#
Ответить
Anonymous
 Как сопоставить два вложенных списка с помощью Automapper

Сообщение Anonymous »

Сущности

Код: Выделить всё

public class PurchaseReq
{
...
public string PrNumber { get; set; } // primary key
public List
 PurchaseReqItems { get; init; } = [];
public List PurchaseReqCharges { get; init; } = [];
}

public class PurchaseReqItem
{
...
public int Id { get; init; } // primary key
public string PrNumber { get; set; } // foreign key
public PurchaseReq PurchaseReq { get; init; } //navigation property
}

public class PurchaseReqCharge
{
...
public int Id { get; init; } // primary key
public string PrNumber { get; set; } // foreign key
public PurchaseReq PurchaseReq { get; init; } //navigation property
}
Dtos

Код: Выделить всё

public class PurchaseReqDto
{
...
public string PrNumber { get; set; }
public List
 PurchaseReqItems { get; init; } = [];
public List PurchaseReqCharges { get; init; } = [];
}

public class PurchaseReqItemDto
{
...
public int Id { get; init; }
public string PrNumber { get; set; }
public PurchaseReqDto PurchaseReq { get; init; }
}

public class PurchaseReqChargeDto
{
...
public int Id { get; init; }
public string PrNumber { get; set; }
public PurchaseReqDto PurchaseReq { get; init; }
}
Профиль сопоставления

Код: Выделить всё

public class PurchaseReqProfile : Profile
{
public PurchaseReqProfile()
{
CreateMap
();

CreateMap()
.ForMember(d => d.PurchaseReqItems, o => o.MapFrom(src => src.PurchaseReqItems))
.ForMember(d => d.PurchaseReqCharges, o => o.MapFrom(src => src.PurchaseReqCharges));
}
}

public class PurchaseReqItemProfile : Profile
{
public PurchaseReqItemProfile()
{
CreateMap();

CreateMap()
.ForMember(d => d.TaxRate, o => o.Ignore());
}
}

public class PurchaseReqChargeProfile : Profile
{
public PurchaseReqChargeProfile()
{
CreateMap();

CreateMap()
.ForMember(d => d.OtherCharge, o => o.Ignore());
}
}
AutoMapper добавляется в службы в Program.cs
AutoMapper версии 13.0.1

Код: Выделить всё

builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
Данные, полученные PurchaseReqRepo

Код: Выделить всё

public async Task
 GetPrForUpdateAsync(string prNumber)
{
ArgumentNullException.ThrowIfNull(prNumber);

return await context.PurchaseReqs
.Include(pr => pr.PurchaseReqItems)
.Include(pr => pr.PurchaseReqCharges)
.SingleOrDefaultAsync(pr => pr.PrNumber == prNumber);
}
Обновить API

Код: Выделить всё

[HttpPut]
[CanUserUpdate(RolesConstant.PurchaseReq)]
public async Task UpdatePurchaseReq([FromBody] PurchaseReqDto purchaseReqDto)
{
if (!short.TryParse(User.Claims.FirstOrDefault(c => c.Type == "sub")?.Value,out var userId))
return Unauthorized();

var purchaseReq = await purchaseReqRepo.GetPrForUpdateAsync(purchaseReqDto.PrNumber);
if (purchaseReq == null)
return NotFound();

if (purchaseReq.IsSubmitted)
return BadRequest(string.Format($"PR ({purchaseReq.PrNumber}) was already submitted for approval and can't be updated."));

mapper.Map(purchaseReqDto, purchaseReq, options =>
options.BeforeMap((prDto, pr) =>
{
pr.RemoveUnMatchedItems(prDto.PurchaseReqItems);
pr.RemoveUnMatchedCharges(prDto.PurchaseReqCharges);
}));

purchaseReq.UpdateBy(userId);

await purchaseReqRepo.SaveChangesAsync();

return NoContent();
}
при сопоставлении PurchaseReqDto с PurchaseReq я получаю сообщение об ошибке AutoMapper, System.InvalidOperationException: экземпляр типа сущности «PurchaseReqCharge» не может быть отслежен, поскольку другой экземпляр со значением ключа «{Id: 3» }' уже отслеживается. При присоединении существующих объектов убедитесь, что прикреплен только один экземпляр объекта с заданным значением ключа.
Я не знаю, что я здесь делаю неправильно.

Подробнее здесь: https://stackoverflow.com/questions/783 ... automapper
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»