Я пытаюсь использовать Entity Framework, и Automapper обновляет мою сущность из моего контракта.
Мой код выглядит так:
var temp = OrderContract;
Order order = dataAccess.FindOne<Order>(x => x.OrderId == temp.OrderId)
?? new Order();
Mapper.Map(OrderContract, order);
if (order.OrderId <= 0)
dataAccess.Add(order);
(Примечание: я использую шаблон репозитория. dataAccess.FindOne вызывает CreateQuery для возврата одной сущности.)
Моя проблема связана с отношениями. Я получаю эту ошибку, когда делаю обновление (вставки работают нормально):
Операция завершилась неудачно: связь не может быть изменена, потому что одно или несколько свойств внешнего ключа не допускают значения NULL. отношения, связанное свойство внешнего ключа устанавливается в значение NULL.Если внешний ключ не поддерживает значения NULL, необходимо определить новое отношение, свойству внешнего ключа должно быть присвоено другое значение, отличное от NULL, или несвязанный объект должен быть удален.
Я предполагаю, что automapper обновляет не так, как я хочу. Из сообщения об ошибке и поиска в Google у меня есть предположил, что мои отношения, которые являются коллекциями (и, возможно, даже те, которые не являются коллекциями), воссоздаются Automapper.
Как я могу сказать Automapper, чтобы он просто обновлял, а не переделывал какие-либо объекты или коллекции?
Предположения:
Я читал, что, возможно, мне нужно использовать параметр UseDestinationValue
для automapper. Я вернулся и поместил это во все свои коллекции. Но когда я это делаю, мои вставки терпят неудачу с нарушением внешнего ключа.
Отображения кода:
Использование UseDestinationValue только в одной коллекции (эта вставляет, но не обновляет):
//+ Source
Mapper.CreateMap<SourceContract, Source>()
.IgnoreAllNonExisting();
//+ SelectedRequirement
Mapper.CreateMap<SelectedRequirementContract, SelectedRequirement>()
.ForMember(x => x.SelectedRequirementId, opt => opt.MapFrom(src => src.RequirementId))
.IgnoreAllNonExisting();
//+ Comment Contract
Mapper.CreateMap<CommentContract, Comment>()
.ForMember(x => x.CommentText, opt => opt.MapFrom(src => src.Comment))
.IgnoreAllNonExisting();
//+ Order Automapper setup
Mapper.CreateMap<OrderContract, Order>()
.ForMember(x => x.Source, opt => opt.MapFrom(src => src.Source))
.ForMember(x => x.Comment, opt => opt.MapFrom(src => src.Comment))
//Although a mapping was created for Comment entity,
//we still need to map the CommentId of the Order entity otherwise it will remain null during an update.
//Another way to handle this would be to Delete CommentId from the Order entity.
//However, if anyone updates (Update from model) OrderDataModel.edmx that property would show up again thus causing
//a null value to be inserted during an update.
.ForMember(x => x.CommentId, opt => opt.MapFrom(src => src.Comment.CommentId))
.ForMember(x => x.SelectedRequirements, opt => {opt.UseDestinationValue(); opt.MapFrom(src => src.Requirements);})
.ForMember(x => x.OrderStateId, opt => opt.MapFrom(src => src.StateId))
.ForMember(x => x.OrderStateId, opt => opt.MapFrom(src => src.StateId))
.IgnoreAllNonExisting();
Использование UseDestinationValue везде (эта не вставляет):
//+ Source
Mapper.CreateMap<SourceContract, Source>()
.IgnoreAllNonExisting();
//+ SelectedRequirement
Mapper.CreateMap<SelectedRequirementContract, SelectedRequirement>()
.ForMember(x => x.SelectedRequirementId, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.RequirementId); })
.IgnoreAllNonExisting();
//+ Comment Contract
Mapper.CreateMap<CommentContract, Comment>()
.ForMember(x => x.CommentText, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.Comment); })
.IgnoreAllNonExisting();
//+ Order Automapper setup
Mapper.CreateMap<OrderContract, Order>()
.ForMember(x => x.Source, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.Source); })
.ForMember(x => x.Comment, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.Comment); })
//Although a mapping was created for Comment entity,
//we still need to map the CommentId of the Order entity otherwise it will remain null during an update.
//Another way to handle this would be to Delete CommentId from the Order entity.
//However, if anyone updates (Update from model) OrderDataModel.edmx that property would show up again thus causing
//a null value to be inserted during an update.
.ForMember(x => x.CommentId, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.Comment.CommentId); })
.ForMember(x => x.SelectedRequirements, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.Requirements); })
.ForMember(x => x.OrderStateId, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.StateId); })
.ForMember(x => x.OrderStateId, opt => { opt.UseDestinationValue(); opt.MapFrom(src => src.StateId); })
.IgnoreAllNonExisting();
Что мне нужно, чтобы я мог вставить и обновить?