2011-03-04 115 views
3

我们很喜欢EntityFramework(CTP5),并将其与ASP.NET MVC3一起使用。实体框架POCO +推荐模式

我不喜欢的是;事情混合在一起。

我可以在同一个班级,这意味着我MIXIN在数据库验证放置DisplayAttributeRequiredAttribute标签RangeAttributeCompareAttribute在一起,一些业务逻辑UI产品总数。我甚至可以将ScriptIgnore属性定制为Json DTO对象。因此,我可以使用相同的POCO类来保留,演示,DTO和业务对象,并作为我的domian模型。

您与EF POCO + MVC3工具集一起遵循哪些设计模式。你有什么图层? 你增加了什么resposibilities到你的类(你的POCO类也是你的域模型)

回答

8

我使用视图模型来解决这个问题。验证和UI呈现属性转到视图模型。在此模式中,控制器使用存储库获取EF模型,将此EF模型映射到视图模型(为此,我使用AutoMapper),并将视图模型传递给视图。因为视图模型包含所有UI呈现属性,所以视图按预期行为。每个视图都必须有自己的视图模型。这意味着您可以将多个视图模型关联到同一EF模型,但包含不同的属性子集和基于视图特定要求的显示格式属性。

该过程也可以以其他方式工作:控制器从视图接收视图模型作为参数。它将视图模型映射回模型并将EF模型传递到存储库。在视图模型上处理UI验证属性是因为您可以在不同的视图中具有不同的验证要求:例如插入/更新视图。在插入视图中,您将创建一个新实体,因此不需要Id属性。在这种情况下,您甚至不会在视图模型上拥有Id属性。在更新视图中相反,Id属性将是必需的。

+0

您的控制器是否直接使用Repository,您是否有服务层来调用行为? – hazimdikenli 2011-03-04 12:45:02

+0

@hazimdikenli,这将取决于我正在开展的项目。如果我有一个复杂的业务逻辑,我会使用服务层。如果没有,并且CRUD存储库操作足以实现我想要的功能,那么我可以直接在控制器中使用它们而不需要服务层。 – 2011-03-04 12:47:01

+0

即使在复杂的项目中,您也有简单的任务,可能会导致使用服务层,从而增加额外的开销,您将如何处理用户通用服务,或者仅在具有业务逻辑的对象上使用服务。假设您正在使用服务发送订单,但是您会使用服务来声明新的UnitOfMeasurement吗? – hazimdikenli 2011-03-04 12:55:56

3

我的POCO类几乎都是域模型,几乎从不查看模型,所以我没有这些问题。

最佳做法是在从控制器传递数据到视图(或作为JsonResult)时使用特殊的“视图模型”类。在这种情况下,您在该视图模型中标记基于UI的属性。在大多数情况下(除了纯粹的粗糙应用程序),您需要显示更多或更少的内容,因此您仍需要一些视图模型(除非直接使用ViewData)。

只有当您想要使用它们进行业务/数据级别验证时,域对象上的数据注释才有意义,这可以采用不同的规则,然后进行UI验证。

如果您想遵循严格的DDD,其中POCO类是域对象=提供对象实例执行域逻辑的方法,您应该更进一步,因为在这种情况下,您的业务应用不应将域对象暴露给控制器。在这种情况下,您最终会在商业门面上暴露数据传输对象并在控制器中使用。我不是纯粹主义者,所以在这种情况下,我打算直接在DTO上使用数据注释,但它取决于其他要求。

+0

你是什么意思最后一段。 – hazimdikenli 2011-03-04 12:45:55

+0

我的意思是,如果你遵循DDD并且你创建了域对象,那么它的方法只能用于商业/域逻辑层。如果你将这样的对象暴露给控制器,你可以在表示层=>违反该规则的情况下调用它们。 – 2011-03-04 12:51:10

+0

感谢您的澄清,所以在这种情况下,您将如何检查订单是否可交付或可取消,并将其作为属性返回ViewModel? – hazimdikenli 2011-03-04 12:58:17