Используйте automapper для обновления Entity Framework Entity

Я пытаюсь использовать 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();

Что мне нужно, чтобы я мог вставить и обновить?

9
задан Vaccano 18 October 2011 в 05:15
поделиться