4

I have an Entity and a ViewModel

public class Order
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    [ForeignKey("DeliveryMethod")]
    public int DeliveryMethodId { get; set; }
    public virtual RouteDeliveryMethod DeliveryMethod { get; set; }
}

and

public class OrderViewModel
{
    public string Name { get; set; }
    public int? DeliveryMethodId { get; set; }
}

My controller receives the view model and uses automapper to map it back to the entity

[HttpPost]
public ActionResult GetQuote(OrderViewModel ordervm)
{
    Order order = Mapper.Map<Order>(ordervm);
    // Do something with the order...

    return View();
}

This is all fine, however after it has done the mapping back to an Order object it doesn't load the DeliveryMethod, DeliveryMethodId has a valid value, but DeliveryMethod is always null.

Shouldn't the DeliveryMethod load due to the lazy loading?

2 Answers 2

2

Automapper looks only at mapped properties. If you have not mapped destination property DeliveryMethod to any of source properties, then it will not be hit during mapping. If property getter is not executed, then entity is not lazy-loaded.

But even if this property was hit, it would not be lazy-loaded anyway. Because Automapper will create new instance of Order class during mapping. But for lazy-loading you need instance of order proxy class which have your DbContext inside. This proxy does loading of related entities when you try to read their values. With plain Order class instance lazy-loading cannot work.

Sign up to request clarification or add additional context in comments.

4 Comments

But shouldn't it load when I access the DeliveryMethod via its getter then, or am I completely misunderstanding how the lazy loading works?
@Rumpetroll see my last update - without order proxy you cannot load navigation property
Ah ok, that makes sense, thanks. So is there any other option than for me to load the object in manually?
@Rumpetroll I would suggest to load it manually. I don't think your database queries should relay on mapper configuration. If you really need to load related entity during mapping, you can use AfterMap method of AutoMapper. But you should have access to DbContext at that point
0

You can resolve your issue quite easily by detaching the (proxy) data entity (ordervm) from EF prior to performing the mapping:

[HttpPost]
public ActionResult GetQuote(OrderViewModel ordervm)
{
    // Detach the data object from EF prior to performing the mapping:
    dbContext.Entry(ordervm).State = EntityState.Detached;

   // The following mapping will no longer lazy load additional (mapped)
   // references unless they have already been (eager) loaded.
   // Additionally, the mapping will no longer raise an exception
   // if it attempts to lazy load additonal references after the 
   // database context has been disposed.


    Order order = Mapper.Map<Order>(ordervm);
    // Do something with the order...

    return View();

}

You may need to do the detachment prior in your data access repository if dbContext is not scope in the above example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.