【问题标题】:ViewModel QuestionsViewModel 问题
【发布时间】:2011-03-06 21:39:13
【问题描述】:

为了简单起见,假设我有一个 CustomerViewModel,我想显示他们的基本信息(姓名、电子邮件、电话等)以及最近的订单列表。

我应该有一个集合属性,比如 OrderListViewModel 类型的 Orders,还是应该使用从 Repository 返回的 POCO 对象?

我想我真正要问的是我是否应该为每个实体都有一个视图模型,然后将那些附加到“父”视图模型的集合?

【问题讨论】:

    标签: asp.net-mvc


    【解决方案1】:

    是的,您应该拥有 ViewModel,但您不必这样做。如果您遵循 DDD,那么您将永远不会有实体到达视图。我已经启动了小型应用程序,我只是将我的域对象用作我的视图的模型,后来随着应用程序的增长,我对设计决定感到后悔。

    这是一篇关于 View Model 模式以及如何使用 Automapper 帮助解决从左到右的附加问题的好帖子:http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx

    http://www.bengtbe.com/blog/post/2009/04/14/Using-AutoMapper-to-map-view-models-in-ASPNET-MVC.aspx

    您的 ViewModel 应该如下所示:

    public class CustomerModel {
        public string Name {get; set;}
        public string Email {get; set;}
        public string Phone {get; set;}
        public OrderModel[] Orders {get; set;}
    
      public class OrderModel {
        public int OrderNumber {get; set;}
        public double OrderTotal {get; set;}
      }
    }
    

    配置 Automapper 并将您的所有关注点分开 (SoC)

    【讨论】:

    • AutoMapper 如何处理订单?我为 Customer --> CustomerModel 创建了一个映射,还为订单创建了一个映射 ---> OrderModel。
    • 做了一个小的编辑并将 OrderModel 类移到 CustomerModel 中,这是因为没有 Customer 的上下文,Order 并不意味着糊状。因此,在 automapper 中,您将设置这些配置文件: CreateMap();和 CreateMap();如果您使用的是 ORM (EF NH) 并启用了延迟加载,这应该“正常工作”。如果您还有其他问题,请告诉我。
    • 感谢您的帮助。您应该有查看和编辑模型,还是每个实体/聚合根只有一个?
    • 我一般有一个 ViewModelProfile : Profile , AddModelProfile : Profile , EditModelProfile : Profile ,这可以因项目而异。如果您有时间,可以观看 Jimmy Bogard(Automapper 的创建者)制作的名为“让控制器节食”tekpub.com/conferences/mvcconf 的精彩视频。 Automapper 部分时长 14 分钟,但整个视频都值得一看。
    【解决方案2】:

    基本上,您应该为每个独特的视图拥有一个独特的视图模型。视图模型应该包含视图将要呈现的所有数据。

    因此,如果您将客户信息与订单一起呈现,则视图模型可能有一个客户实例和一个订单列表:

    class ViewModel
    {
        Customer Customer { get; set; }
        IEnumerable<Order> Orders { get; set; }
    }
    

    我建议使用视图模型,即使一个简单的业务对象就可以了。这使它更易于维护,而且众所周知,需求会发生变化。

    AutoMapper 是一款出色的工具,让处理视图模型变得轻而易举。

    【讨论】:

    • @alexn - 我应该有一个 OrderViewModel 集合而不是 Orders 集合吗?
    • 为什么要创建一个 ViewModel 然后将你的实体暴露给视图?使用延迟加载,这与将客户发送到视图并调用 customer.orders 一样???
    • @Paul 从视图中查询数据库是一种不好的做法(我假设您的意思是)。 NHProf 的这篇文章很好地解释了这一点。 nhprof.com/Learn/Alerts/QueriesFromViews
    • @alexn - 我 100% 同意这一点,但在视图中使用域中的实体也是一种不好的做法。 blogs.msdn.com/b/simonince/archive/2010/01/26/…
    • 为什么在视图中使用域对象是不好的做法?
    【解决方案3】:

    不要无缘无故地创建视图模型。视图模型应提供将模型与视图解耦的特定价值,并添加您不想放入模型中的特定视图需要的其他项目(下拉列表等)。视图模型应将 1 到 1 映射到特定视图。

    如果您现在没有上述需求,请不要创建它。

    我认为从 POCO 开始并在需要时创建视图模型没有任何问题。在您需要在视图和模型之间解耦时,我认为重构和创建视图模型没有什么大问题。对于琐碎的情况,我会避免预先进行过度工程,但要知道您的目标是最终将视图模型作为一种解决方案,以避免耦合或添加视图需要的额外内容。

    【讨论】:

      【解决方案4】:

      理想情况下,您应该为视图处理的每个实体都有视图模型。有时当实体太琐碎时,我猜你可以跳过视图模型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-23
        相关资源
        最近更新 更多