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

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

Сообщение Anonymous »

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

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

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

    Свяжитесь с уровнем репозитория, чтобы получить существующую сущность из База данных
  • map entityrequestdto to entity (получено в шаге 2.1) для обновления существующих значений (Из запроса DTO к объекту) с использованием Automapper
  • Проверьте обновленную сущность
  • Свяжитесь с уровнем хранилища, чтобы снова сохранить изменения, внесенные в Entity
[*] Уровень репозитория получает обновленную сущность для уровня службы и сохранить Изменения в базе данных < /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>

 осложнений < /h2>
Служба полагается на автоматиптель, чтобы сделать частичное обновление, чтобы помочь заменить свойства, присутствующие в Запросить 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). < /p>

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

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>
Кроме того, используются и настроены следующие пакеты в программе. Automapper < /li>
automapper.collection.entityFrameWorkCore
< /ul>
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>

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

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

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