Игнорировать идентификатор при сопоставлении объекта внутри метода put с помощью MapperleyC#

Место общения программистов C#
Ответить
Anonymous
 Игнорировать идентификатор при сопоставлении объекта внутри метода put с помощью Mapperley

Сообщение Anonymous »

Основной причиной этого вопроса является переход с AutoMapper на Mapperly из-за того, что последняя версия работает быстрее.
У меня проблема в том, что я не знаю, как автоматически сопоставлять UpdateBarDTO на Bar, игнорируя идентификатор Bar при сопоставлении, чтобы он изменял правильный объект базы данных, не выдавая ошибку:

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

System.InvalidOperationException: The property 'Bar.Id' is part of a key and so cannot
be modified or marked as modified. To change the principal of an existing entity with an
identifying foreign key, first delete the dependent and invoke 'SaveChanges',
and then associate the dependent with the new principal.

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

public record class UpdateBarDTO
(
[Required][StringLength(255)] string Name,
[Required] string Address,
[Required] string PhoneNumber,
[Required] string Email,
string Website,
string CuisineType,
[Required] string OpeningHours,
DateTime CreationDate
);

public class Bar
{
public int Id { get; set; }
public required string Name { get; set; }
public required string Address { get; set; }
public required string PhoneNumber { get; set; }
public required string Email { get; set; }
public string? Website { get; set; }
public string? CuisineType { get; set; }
public required string OpeningHours { get; set; }
public DateTime? CreationDate { get; set; }
}

Мне удалось найти решение, используя следующее:
Используйте UpdateBarFromDto(), чтобы установить идентификатор, чтобы база данных знала, какой объект обновлять

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

[Mapper]
public partial class BarMapper
{
public partial Bar ToUpdateBar(UpdateBarDTO bar);
public Bar UpdateBarFromDto(UpdateBarDTO updateBarDTO, Bar bar)
{
var dto = ToUpdateBar(updateBarDTO);
dto.Id = bar.Id;
return dto;
}

Полезная нагрузка: меняется только имя

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

PUT 
Content-Type: application/json

{
"Name": "Sunset Lounge Skyy",
"Address": "123 Ocean Drive, Miami, FL 33139",
"PhoneNumber": "305-555-1234",
"Email": "contact@sunsetlounge.com",
"Website": "",
"CuisineType": "Seafood",
"OpeningHours":"Monday: 10:00 AM - 11:00 PM,Tuesday: 10:00 AM - 11:00 PM,Wednesday: 10:00 AM - 11:00 PM,Thursday: 10:00 AM - 11:00 PM,Friday: 10:00 AM - 12:00 AM,Saturday: 10:00 AM - 12:00 AM,Sunday: 10:00 AM - 10:00 PM",
"CreationDate": "2020-08-15T00:00:00"
}

Контроллер

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

//PUT /bars/1
group.MapPut("/{id}", async (int id, UpdateBarDTO updatedBar, ServitusDbContext dbContext) =>
{
var existingBar = await dbContext.Bars.FindAsync(id);

if (existingBar is null)
return Results.NotFound();

//set the id of updatedBarDTO
var bar = new BarMapper().UpdateBarFromDto(updatedBar, existingBar);

//locate the bar you want to update, map it to DTO and set the values
dbContext.Entry(existingBar)
.CurrentValues
.SetValues(bar);

await dbContext.SaveChangesAsync();

return Results.NoContent();
});

Для тех, кто знает AutoMapper, я хочу добиться того же, что и эта строка:

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

var bar = mapper.Map(updatedBar, opt => opt.AfterMap((src, dest) => dest.Id = id));

Большое спасибо!

Подробнее здесь: https://stackoverflow.com/questions/787 ... h-mapperly
Ответить

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

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

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

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

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