Условная карта "Null" не нулевых типов, перечисления и коллекций с автоматическим автоматом в C#C#

Место общения программистов C#
Anonymous
 Условная карта "Null" не нулевых типов, перечисления и коллекций с автоматическим автоматом в C#

Сообщение Anonymous »

Я разрабатываю патч конечную точку REST, чтобы сделать частичное обновление для EF Core Entity. Все свойства в запросе DTO (

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

EntityRequestDto
) помечены как нулевые, а фактическая сущность () будет помечен как необходимый или нулевый в соответствии со разработанной структурой данных.
Приложение разработано с использованием шаблона репозитория (контроллер> служба> Репозиторий), поэтому поток обновления будет похожим на это:
  • контроллер. Layer
  • Служба получает EntityRequestDto для выполнения следующих действий:

    Свяжитесь с уровнем репозитория, чтобы получить существующую сущность из базы данных
  • map entityRequestdto
  • map entityRequestdto (struction> endityRequestdto . (От запроса DTO к объекту) С помощью Automapper
  • Проверка обновленной объекты
  • Следите за слоем репозитория, чтобы сохранить изменения, внесенные в Entity
repositor. в базе данных < /li>
< /ol>
Приведенные выше шаги равны следующему коду: < /p>

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

[Authorize]
[Route("[controller]")]
public class EntityController(IEntityService service) : ControllerBase
{
[HttpPatch("{id}")]
public IActionResult Update(Guid id, [FromBody] EntityRequestDto requestDto) =>
Ok(service.UpdateAsync(id, requestDto).Result);
}

public class EntityService(IEntityRepository repository): IEntityService
{
public async Task UpdateAsync(Guid id, EntityRequestDto requestDto)
{
var existingEntity = await repository.GetAsync(id);

if (existingEntity is null) return null;

mapper.Map(requestDto, existingEntity);
await validator.ValidateAndThrowAsync(existingEntity);
await repository.UpdateAsync(existingEntity);

return mapper.Map(existingEntity);
}
}

public class EntityRepository(EntityContext context) : IEntityRepository
{
public async Task UpdateAsync(Entity entity)
{
await _context.SaveChangesAsync();
return entity;
}
}
< /code>
 Осложнения < /h3>
Служба полагается на автоматическое обновление, чтобы сделать частичное обновление, чтобы помочь заменить свойства, присутствующие в запросе DTO в существующую сущность, оставляя другие свойства нетронутыми.  Модель: < /p>
public enum EntityType
{
TYPE_1,
TYPE_2
}

public class Entity
{
public required Guid Id { get; set; }
public required EntityType Type { get; set; }
public required int IntegerProperty { get; set; }
public required string StringProperty { get; set; }
public List EntityItems { get; set; } = [];
}

public class EntityRequestDto
{
public EntityType? Type { get; set; }
public int? IntegerProperty { get; set; }
public string? StringProperty { get; set; }
public List EntityItems { get; set; } = null;
}

public class EntityItems
{
public required Guid Id { get; set; }
public required string Name { get; set; }

public required Guid EntityId { get; set; }
public Entity Entity { get; set; } = null!;
}
потребует сопоставления между запросом DTO и объектом для выполнения частичного обновления, в противном случае NULL или значение по умолчанию будет отображено в существующую сущность (что должно быть нетронуто, поскольку они не присутствуют в DTO-запросе).

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

public class Mapper : Profile
{
public Mapper()
{
// If an integer property in the request DTO is `null`, do not map and preserve the value from the existing entity (prevent the default value of `0` get mapped into the entity)
profile.CreateMap().ConvertUsing((src, dest) => src ?? dest);

// If an enum property in the request DTO is `null`, do not map and preserve the value from the existing entity (prevent the default value of first enum constant or position `0` get mapped into the entity)
profile.CreateMap().ConvertUsing((src, dest) => src ?? dest);

// If `EntityItems` from the `EntityRequestDto` is `null`, do not map it to the entity (which will remove all existing items in the entity)
profile.CreateMap().ForMember(dest => dest.EntityItems, opt =>
{
opt.PreCondition((src) => src.EntityItems != null);
opt.MapFrom(src => src.EntityItems);
});

// For other properties, do not map if the value in the `EntityRequestDto` is `null`
profile.CreateMap().PreserveReferences()
.EqualityComparison((requestDto, entity) => requestDto.Id == entity.Id)
.ForAllMembers(option => option.Condition((_, _, sourceMember) => sourceMember != null));
}
}
< /code>
Кроме того, используются и настроены следующие пакеты в программе. PrettyPrint-Override ">public static class Program
{
private static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddAutoMapper((serviceProvider, config) =>
{
config.AddCollectionMappers();
config.UseEntityFrameworkCoreModel(serviceProvider);
}, typeof(Mapper).Assembly);

// ...
}
}
< /code>
 Вопрос < /h3>
Как вы можете видеть, это кажется обходным процессом, потому что для одного объекта требуется несколько сопоставлений для не нулевых типов, перечисления и коллекций, которые присутствуют внутри сущности. Свойство непреднамеренно обновляется до 0 
при каждом обновлении)
Мне интересно, что такое правильный метод для выполнения частичного обновления в таком сценарии с помощью Automapper?

Подробнее здесь: https://stackoverflow.com/questions/794 ... ith-automa

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