我正在开发一个单人ASP.NET MVC 3项目(我完全控制数据库架构和代码),我正在尝试在数据库优先和POCO与我的EF4模型之间做出决定,或者我是否应该先代码。
我想要实现的主要功能是使用DataAnnotation属性来装饰我的模型,这样我就可以在执行任何持久性之前强制执行模式验证。查看关于模型验证的Scott Guthrie's article与MVC 2,他谈到了关于使用代码优先(步骤2)执行此操作的文章,并使用“伙伴类”(模型优先(或数据库优先))执行此操作(步骤5)。
我历史上使用SQL Server设计器GUI(和脚本)完成了我的数据库设计,因此我非常高效,严格来说,在数据库设计方面。但是,除非我放弃使用DataAnnotation属性进行装饰验证的想法,否则我将违反DRY,不仅要在两个类中具有模型属性,而且必须在两个地方构建我的模式。
我正在寻找那些对这两种方法都有经验的人(甚至是一种方法),并且可以提供他们去哪种方式的反馈,他们为什么决定这种方式,以及他们如何发现它的工作方式。我还想知道我是否会更好地完全不同,使用像Fluent验证这样的工具,或者甚至完全放弃域模型级验证,并在服务和视图模型中保持我的验证。
答案 0 :(得分:4)
首先Code First在CTP中,因此没有上线许可证。如果这是一个在未来几个月内交付的项目,那么决定是模型优先。
话虽如此,使用DataAnnotations的Code First类比带有好友类的Model First POCO更干净,但根据我的经验,最重要的是明确的意图。只要您的设计清晰且最重要的是一致,任何一种方法都是合适的。
对于一个小项目(即你所说的一个人),我会说你可能会通过Model First提高效率并通过edmx进行设计。对于来自架构第一背景的人来说,这也会让您感到更舒服。然而,为了让POCO类能够很好地运行,例如安装POCO T4模板,然后修改项目中创建的T4模板以将POCO拉入单独的程序集,您需要进行一些操作。你不希望它们在DAL组件中,它们将从那里开始。然后,您将决定使用部分类来实现DataAnnotations的程度。因为我不同意许多人认为这些设计很差。
在MVC项目中,当您决定使用ViewModels时,您将使用DataAnnotations使用任一种方法来解决无处不在的DRY问题。此时,您会突然意识到,只有在您将这些类直接发送到视图时,才能使用模型的大量注释进行验证。如果您决定保持视图的轻量级并使用ViewModel,则必须在ViewModel上重复DataAnnotations,否则您将在模型级别留下验证错误,但除了手动添加之外,无法将其转换为ModelState。首先没有代码或模型首先解决这个问题所以你需要相应地进行设计。我们亲自去了混合,接受了破坏DRY的程度。
答案 1 :(得分:3)
您在寻找什么类型的验证?您是否希望将用户输入验证规则注入实体,还是希望验证层仅在数据库操作之上?
有很多纯粹主义的讨论,实体不应该包含验证属性,因为你永远不会在视图中使用它们 - 你将使用特殊类型的视图模型类,验证参数将直接在该类的属性上。对于中型和大型项目,我同意。对于简单的数据管理项目,它更像是数据形式(只是CRUD操作),我不同意,因为它是你不需要的额外复杂性。
EF代码首先引入了用作数据库层验证的数据注释(顺便说一下,数据层验证可以与ui验证完全不同)。在Code中引入此功能之前,我尝试使用EDMX文件完全相同的方法。对于EF T4 POCO模板生成的类,您也can define validation attributes。我的验证实现(基于反射)的问题是,如果我执行了大量更新和插入,那么它非常慢 - 我还没有先将它与代码进行比较。
修改强>
基于ADO.NET团队博客中的current announcement下一个EF版本(RC计划于3月底)将支持所有三种方法的验证 - 代码优先,数据库优先,模型优先。我仍然不确定它是否意味着支持DbContext和基于ObjectContext的实现中的验证。
答案 2 :(得分:0)
你在这里并没有真正验证DRY。 DRY的概念比简单的代码重复更加细微。有可接受的权衡,特别是考虑到耦合问题时。
当人们提出这个问题时,如果你经常搜索这个问题,我通常会将它们引用到[有界概念] [1]的DDD概念中。在验证方面使用[Remote]
并强制执行DRY往往会在一个地方聚集大量问题并合并多个层的职责。业务逻辑与持久性和数据完整性逻辑(非空)。