Automapper: How to map IList to EntityCollection

2019-09-15 10:33发布

问题:

I am using Automapper v1.1, since I am using .NET 3.5 as well as using Entity Framework.

I'm trying to map a ViewModel to Model but keep running into errors. I have the below sample classes:

OrderViewModel

public class OrderViewModel{
  public string OrderNo { get; set; }
  public IList<OrderItem> DisplayItems { get; set; }

  public OrderViewModel(){
    DisplayItems = new List<OrderItem>();
  }

}

Order (note: this class is auto-generated by EF)

public class Order{
  public string OrderNo { get; set; }
  public EntityCollection<OrderItem> OrderItems { get; set; }

  ...

}

OrderItem (note: this class is auto-generated by EF)

public class OrderItem{
  public string Name { get; set; }
  public int Quantity { get; set; }
  public int Price { get; set; }

  ...

}

My Function

public void MyFunction(OrderViewModel source){

  //initialize mapping
  Mapper.CreateMap<OrderViewModel, Order>().ForMember(dest => dest.OrderItems, opt => opt.MapFrom(src => src.DisplayItems));

  //map viewmodel to model
  var model = Mapper.Map<OrderViewModel, Order>(source);

  //does not reach this point
}

When I tried to trace, it is stopping when it tries to map the DisplayItems to the OrderItems property. I am receiving the following error regarding it:

System.InvalidOperationException: Requested operation is now allowed when the owner of this RelatedEnd is null. RelatedEnd objects that were created with the default constructor should only be used as a container during serialization.

What am I doing wrong? What's the correct way to map an IList to an EntityCollection using Automapper? I am doing this because I do not want to write an iterative code just to copy / transfer items from one collection to the other.

回答1:

I think it's basically because you're explicitly creating the map from a List to a EntityCollection type - from what I've seen it seems people end up doing this iteratively (I haven't seen a direct cast/conversion yet). But if you want it to work, this approach seems to get the job done.

Doing a quick search you can find some examples where this is managed by using more or less custom mapper code, with iteration. Here's a post with a few examples.

Here's another one that expresses it more clearly.

Good luck!