2010-06-26 32 views
2

我打算在大型项目中使用实体框架4。为什么不使用EF在大型项目中生成的类?

我知道许多专业程序员建议依赖于我的业务类而不是EF模型类。

其实我脑子里有声音告诉我“不要依赖那些生成的类!只要让你的手变脏,不要让其他人为你做。!!”

但实际上我不知道在这么大的“企业”项目中使用这些生成的类的问题在哪里。

所以请让我明白为什么?

回答

5

使用EF生成的类绝对没有错。这就是他们在那里。

但是,如果你误用了这项技术,你会遇到很多问题。例如,很多初学者会尝试使用这些EF生成的类的所有内容。他们将接受这些类,通过WCF或Remoting跨AppDomain边界编组它们,也许它们将在它们的前端绑定到它们。这可能适用于基于CRUD的快速和肮脏的应用程序,但它不适用于具有任何实际大小的任何内容。

为什么不呢?因为EF生成的类是在应用程序的数据“域”中建模的,而不是“域”表示。用户可能想要与之交互的内容通常不是与数据库中的表格1:1对象。例如,用户可能有一个“产品”网格。在这个网格内,将包括该产品的总售价以及有关该产品的某些指示性数据。尽管指示性数据(名称,大小等)可能会直接来自产品表,并且因此来自EF的生成的产品类,但是汇总数据(出售的总美元)是合计值。

我们通常所做的就是在我们的服务中使用EF生成的类,然后使用该服务将EF类转换为ViewModels,然后使用WPF绑定到我们的前端(或任何您最喜欢的技术) 。这让我们分离了我们正在寻找的关注点。

+0

谢谢你的好解释。但我不是在说使用ViewModel。我正在讨论在ViewModel和EF Model“我的商业模型”层之间创建新的图层“或轮胎”。这种分离是好事还是只是一项额外的工作。 – 2010-06-26 15:50:50

+0

这几乎总是额外的工作。是的,你可以,也许应该在你的类中创建另一个层,你的服务用它来创建你的ViewModels/etc,但是创建一个全新的层,你必须在AppDomain中编组另一类型的对象几乎总是一个错误 - 一个当涉及到性能和可伸缩性时,您经常付出沉重的代价。 – 2010-06-26 16:10:40

+0

我同意戴夫。到目前为止,我只在小型项目中使用过EF,但我还没有找到需要单独的Business Object层; EF实体一直足够灵活以充当BOs。 – 2010-06-26 16:14:38

1

除了Dave的很好的答案之外,我想提一下使用生成的类的另一个重要缺点:它们来源于一个公共基类(EntityObject)。如果现有的域模型具有自己的继承层次结构,则可能会造成问题,因为.NET中不支持多继承。

1

如果您的项目很大,我建议您关注域驱动开发。每个域类都包含许多组件:EF实体属性,行为属性注入(格式化数据,解析,转换,复制,验证,配置)。

如果您遵循单一责任原则,每个班级应该只有1个责任。 EF模型类应该用于存储数据并与EF基础结构进行通信以生成运行时SQL。其他课程将负责格式化,转换,验证和转移。

当类型数量增加时,您需要使用Facade模式集中或组织它们。这些Facades是特定于域的类型。因此,如果您从生成EF模型开始,然后构建支持类型(格式化程序,验证程序...),并最终创建域类型,那么您将不会获得更高的协作和分发能力,因为您可能获得相反的结果。首先构建您的域类型,构建模拟和单元测试,然后与同伴共享它们,让它们将域对象的函数与EF模型连接起来。这就是你如何做域驱动开发。

+0

我想问一下更多的解释。任何例子或参考将不胜感激。 – 2014-04-25 19:23:03

+0

实体框架生成的模型类。它们应该用于保存数据。您需要创建具有LOB函数和EF实体作为类成员的域类。这样做会将状态/数据(通过EF实体)存储的问题与数据的实际转换(通过非EF类)分开。 – Believe2014 2014-04-27 03:05:01

+0

我最近更新了项目的主页,以宣布即将发布的版本和功能。如果您遵循单一职责原则,每个班级只应承担一项责任。 EF模型类应该用于存储数据并与EF基础结构进行通信以生成运行时SQL。其他课程将负责格式化,转换,验证和转移。 – Believe2014 2014-04-28 18:34:04

1

将EF生成的类一直暴露给Javascript时,需要特别小心。

首先,您可能会暴露出太多超出您需要的字段。这将增加有效负载并使攻击者可以轻松猜测数据库模式。其次,如果您还让MVC Model Binder将HTTP(通过请求主体,URL或任何方式)数据反序列化到EF模型中,然后将其直接保存到数据库中,则存在很大的风险。任何人都应该能够缓和HTTP请求,向您发送一个JSON对象,以覆盖您不希望的字段。想想这个购物车对象:

{cartItems: [{itemId:1, quantity:100, product:{ productId:23, price:0 }}]} 

如果我能在一个product传递与价格0和有效的productId,EF将覆盖指定产品的价格在你的数据库。

+0

但是,当你使用ViewModels时,这不是问题。我将ViewModels与我的视图一起使用,并使用POCO EF类与我的DAL/BLL – 2014-04-27 07:37:07

+1

,如果您可以将BLL模型和DAL模型中的视图模型分开,则这不会成为问题。然而,很多博客似乎主张直接在DAL模型上添加属性,以使它们成为View模型,这可能是一个很大的风险。 – Believe2014 2014-04-27 22:03:16

相关问题