#c# #automapper #.net-core-2.2
#c# #автоматизатор #.net-core-2.2
Вопрос:
В моем проекте Entity Framework Core 2.2 API я создал контекст. Поскольку он представляет данные из моей базы данных, я получаю записи типа —
entity.Property(e => e.Active)
.IsRequired()
.HasDefaultValueSql("((1))");
где Active
требуется значение по умолчанию 1.
Я также сопоставляю объекты с помощью AutoMapper.
Мой класс MappingEntity —
public class MappingEntity : Profile
{
public MappingEntity()
{
CreateMap<MemberUpdate, Member>();
}
}
который сопоставит ViewModel MemberUpdate
с моим объектом базы данных Member
Кажется, я теряю значение по умолчанию в своем контроллере —
public ActionResult Account(int id, [FromBody]MemberUpdate updatedMember)
{
Member member = _memberRepository.GetById(id);
//HERE MY MEMBER OBJECT IS CORRECT AND `ACTIVE` HAS IT'S DEFAULT VALUE
member = _mapper.Map<Member>(updatedMember);
//HERE MY MEMBER OBJECT IS INCORRECT AND THE ACTIVE FIELD DOES NOT SHOW THE DEFAULT VALUE
//proceed to save back to the database
}
Существует ли настройка AutoMapper для сохранения значения по умолчанию?
Ответ №1:
AutoMapper не может сохранить ваше значение по умолчанию, потому что он даже не знает, что оно существует.
.HasDefaultValueSql("((1))");
Это параметр, который EntityFramework использует, когда он создает объект, но в этом случае AutoMapper создает объект, поэтому информация теряется.
Однако, что вы могли бы сделать, это применить некоторую пользовательскую логику к вашему отображению, чтобы впоследствии добавить значение по умолчанию. Это выглядело бы примерно следующим образом:
CreateMap<MemberUpdate, Member>()
.AfterMap((memberUpdate, member) =>
member.Active = memberUpdate.Active == default(int) ? 1 : memberUpdate.Active);
Это просто выполняет сопоставление по умолчанию между Member
и MemberUpdate
, а затем впоследствии присваивает значение по умолчанию, которое вы хотите Member
.
В качестве альтернативы, вы могли бы изменить свою модель, чтобы внутри нее было значение по умолчанию, вместо того, чтобы выполнять это назначение извне, например:
public int Active { get; } = 1;
Хотя я сомневаюсь, что этот вариант будет вам полезен, поскольку вы хотите, чтобы EF справился с этим за вас. Я бы предложил где-нибудь преобразовать жестко закодированное 1
значение в константу, а затем использовать эту константу в вашем отображении AutoMapper и в настройках EF.
Надеюсь, это поможет.
Комментарии:
1. Возможно, я не совсем ясно выразился. Принудительно ли это сопоставление значения после сопоставления? Что, если входящая viewmodel устанавливает его на что-то другое?
2. Не видя ваших моделей, мне, к сожалению, пришлось сделать пару предположений. Одним из них было то, что ваша входящая модель на самом деле не имела такого свойства, но, похоже, я ошибался в этом. Можете ли вы сказать мне, каково ожидаемое поведение, когда входящая viewmodel имеет значение, по сравнению с тем, когда оно не имеет?
3. Когда входящая модель обладает этим свойством, сопоставьте ее. Если это свойство не было установлено для входящей модели, используйте базу данных по умолчанию
4. Хорошо, я только что отредактировал код сопоставления в своем сообщении, чтобы обработать этот вариант использования. Надеюсь, это поможет!