如何使用Automapper函数调用递归地将实体映射到视图模型?

时间:2013-12-13 18:34:57

标签: c# asp.net .net automapper

脱离我之前的问题 - > How to map .NET function call to property automatically?

我想要映射到视图模型的一些相关实体对象,每个到视图模型的映射都需要调用映射函数。

棘手的部分是实体函数返回另一个需要映射到它的视图模型的实体。流程有点像这样。

  

CartEntity> CartViewModel> CartEntity.GetCartItems()>   CartViewModel.CartItems> CartEntity.GetCartItems()。GetItem()>   CartViewModel.CartItems.Item>   CartEntity.GetCartItems()。GetItem()。GetProduct()>   CartViewModel.CartItems.Item.Product

这是类,我试图以递归方式构建一个用每个对象填充的嵌套集。

实体:

public class CartEntity {
    public long Id {get; set;}
    public List<CartItem> GetCartItems() {
          return Repository.GetAll<CartItem>();
    }
}

public class CartItem {
    public long Id {get; set;}
    public long ItemId {get ; set;}
    public Item GetItem() {
          return Repository.Get<Item>(ItemId);
    }
}

public class Item {
    public long Id {get; set;}
    public long ProductId {get; set;}
    public Item GetProduct() {
          return Repository.Get<Product>(ProductId);
    }
}
public class Product {
    public long Id {get; set;}
}

查看模特:

public class CartViewModel {
    public long Id {get; set;}
    public List<CartItemViewModel> {get; set; }
}

public class CartItemViewModel {
    public long Id {get; set;}
    public ItemViewModel Item {get; set; }
}

public class ItemViewModel {
    public long Id {get; set;}
    public ProductViewModel Product {get; set; }
}

public class ProductViewModel {
    public long Id {get; set;}
}

2 个答案:

答案 0 :(得分:3)

如果您愿意更改模型,运行AutoMapper应该非常简单(如果没有,请跳到底部)。

首先,由于您的评论表明您需要从模型中调用您的存储库,我建议将它们更改为只读属性。例如:

public class CartItem {
    public long Id {get; set;}

    public long ItemId {get ; set;}

    public Item Item {
        get {
            return GetItem();
        }
    }

    private Item GetItem() {
          return Repository.Get<Item>(ItemId);
    }
}

此外,如果您不想在每次时调用数据库,那么您可以添加一个延迟加载的支持字段:

.Item

从那里,您可以像这样设置AutoMapper:

public class CartItem {
    private Item _item;

    public long Id {get; set;}

    public long ItemId {get ; set;}

    public Item Item {
        get {
            return _item ?? (_item = GetItem());
        }
    }

    private Item GetItem() {
          return Repository.Get<Item>(ItemId);
    }
}

如果您不想更改模型以使用属性(或者如果您不能),则可以在地图上添加// one-time, static configuration: Mapper.CreateMap<CartEntity, CartViewModel>(); Mapper.CreateMap<CartItem, CartItemViewModel>(); Mapper.CreateMap<Item, ItemViewModel>(); Mapper.CreateMap<Product, ProductViewModel>(); // running the mapper: var cartViewModel = Mapper.Map<CartViewModel>(cart); 配置,以指定对每个项目执行的操作:< / p>

ForMember

答案 1 :(得分:3)

您不需要做任何复杂的事情,AutoMapper支持:

// one time config
Mapper.CreateMap<CartEntity, CartViewModel>();
Mapper.CreateMap<CartItem, CartItemViewModel>();
Mapper.CreateMap<Item, ItemViewModel>();
Mapper.CreateMap<Product, ProductViewModel>();
Mapper.AssertConfigurationIsValid();

// whenever you map
CartEntity cart = // whatever
CartViewModel vm = Mapper.Map<CartViewModel>(cart);