为什么我们需要实体对象?

对于目前公认的企业应用程序devise模式的优点,我真的需要看到一些诚实而深思熟虑的辩论。

我不相信实体对象应该存在。

通过实体对象,我指的是我们倾向于为我们的应用程序构build的典型事物,如“人员”,“账户”,“订单”等。

我目前的devise理念是这样的:

  • 所有数据库访问都必须通过存储过程完成。
  • 无论何时需要数据,调用存储过程并遍历SqlDataReader或DataTable中的行

(注意:我也用Java EE构build了企业应用程序,请将java代码replace为我的.NET示例)

我不是反OO。 我为了不同的目的写了大量的类,而不是实体。 我承认,我写的很大一部分类是静态辅助类。

我不是在玩玩具。 我正在谈论的是跨多台机器部署的大量大量事务性应用程序。 Web应用程序,Windows服务,Web服务,B2C交互,你的名字。

我使用了OR映射器。 我写了几个。 我已经使用了Java EE堆栈,CSLA和一些其他的等价物。 我不仅使用它们,而且在生产环境中积极开发和维护这些应用程序。

我得出了一个经过testing的结论,即实体对象正在阻碍我们,没有它们,我们的生活将变得如此简单。

考虑一下这个简单的例子:你得到了一个关于你的应用程序中某个页面的支持调用不能正常工作,也许其中一个字段没有被保持。 使用我的模型,分配到查找问题的开发人员只打开3个文件 。 一个ASPX,一个ASPX.CS和一个带有存储过程的SQL文件。 这个问题可能是存储过程调用中缺less的参数,需要花费几分钟的时间来解决。 但是对于任何实体模型,您总是会启动debugging器,开始逐步执​​行代码,最终可能会在Visual Studio中打开15-20个文件。 当你下到堆栈底部时,你忘记了开始的地方。 我们一次只能把这么多东西留在脑海里。 软件非常复杂,无需添加任何不必要的图层。

开发的复杂性和故障排除只是我抱怨的一个方面。

现在我们来谈谈可扩展性。

开发人员是否意识到,每次编写或修改任何与数据库交互的代码时,他们都需要对数据库的确切影响进行深入的分析。 而不仅仅是开发副本,我的意思是生产的模仿,所以你可以看到,你现在需要的对象的额外的列只是使当前的查询计划失效,并在1秒内运行的报告现在需要2分钟,只是因为你添加了一列到select列表? 事实certificate,你现在需要的索引是如此之大,DBA将不得不修改你的文件的物理布局?

如果让人们从抽象的物理数据存储区离得太远,他们将对需要扩展的应用程序造成严重破坏。

我不是一个狂热者。 我可以相信,如果我错了,也许我是,因为有这样一个强大的推动LINQ的SQL,ADO.NET的EF,Hibernate的,Java EE的等请考虑通过您的回应,如果我失去了一些东西真的想知道这是什么,为什么我应该改变我的想法。

[编辑]

看起来这个问题突然激活了,所以现在我们有了新的评论function,我直接评论了几个答案。 感谢您的回复,我认为这是一个健康的讨论。

我应该更清楚地说我正在谈论企业应用程序。 我真的不能评论某人在桌面上运行的游戏或移动应用程序。

有一件事我不得不放在这里,回答几个类似的答案:正交性和关注点的分离经常被引用为实体/ ORM的理由。 对我而言,存储过程是我能想到的关注点分离的最好例子。 如果你不允许所有其他的访问数据库,而不是通过存储过程,那么理论上可以重新devise你的整个数据模型,而不会破坏任何代码,只要你维护存储过程的input和输出即可。 他们是合同编程的完美例子(只要你避免“select*”并logging结果集)。

问一个已经在这个行业工作了很长时间的人,他曾经用过很长时间的应用程序:在数据库已经存在的时候,有多less应用程序和UI层来了? 当有4个或5个不同的持久层生成SQL来获取数据时,调整和重构数据库有多困难? 你不能改变任何东西! ORM或任何生成SQL的代码都会locking您的数据库

我认为这归结于应用程序的“逻辑”有多复杂,以及在哪里实现。 如果你所有的逻辑都在存储过程中,你所有的应用程序都调用这些过程并显示结果,那么开发实体对象的确是浪费时间。 但是对于一个应用程序来说,这些对象具有丰富的相互作用,而数据库只是一个持久性机制,这些对象就有价值。

所以,我会说没有一个通用的答案。 开发人员需要注意的是,有时,尝试过于OO会导致比解决问题更多的问题。

理论认为,高度凝聚力,松耦合的实现是前进的方向。

所以我想你是在质疑这种方法,即分离问题。

我的aspx.cs文件应该与数据库交互,调用一个存储过程,并理解IDataReader?

在团队环境中,尤其是在技术人员较less处理应用程序的aspx部分的情况下,我不需要这些人能够“触摸”这些东西。

将我的域从数据库中分离出来,保护我免受数据库结构的影响,当然是件好事? 当然数据库的有效性是绝对重要的,所以让那些在这方面最优秀的人在一个地方处理这个问题,尽可能减less对系统其他部分的影响。

除非我误解你的方法,否则数据库中的一个结构变化可能会对应用程序表面产生很大的影响。 我看到,这种关注的分离使我和我的团队能够最小化这一点。 此外,任何新的团队成员都应该更好地理解这种方法。

另外,您的方法似乎主张应用程序的业务逻辑驻留在数据库中? 这对我来说是错误的,SQL非常擅长查询数据,而不是expression业务逻辑。

有趣的想法,虽然它感觉离aspx中的SQL只有一步之遥,这从我那古老的非结构化asp日子里,让我充满恐惧。

一个原因 – 将您的域模型从数据库模型中分离出来。

我所做的是使用testing驱动开发,所以我先写我的用户界面和模型图层,数据层被模拟,所以用户界面和模型是围绕特定于域的对象构build的,然后将这些对象映射到我正在使用的技术数据层。 让数据库结构决定应用程序的devise是个不错的主意。 在可能的情况下先写应用程序,让它影响数据库的结构,而不是相反。

对我来说,归结为我不希望我的应用程序关心如何存储数据。 我可能会因为这样说而被打耳光……但是你的应用程序不是你的数据,数据是应用程序的人工产物。 我希望我的应用程序能够根据客户,订单和项目进行思考,而不是像DataSets,DataTables和DataRows这样的技术,因为谁知道这些技术将会持续多久。

我同意总会有一定的耦合,但是我更喜欢耦合是向上而不是向下。 我可以调整树的四肢和树叶,比改变它的树干更容易。

我倾向于保留sprocs进行报告,因为查询往往比应用程序的一般数据访问有点麻烦。

我也倾向于在这种情况下尽早地进行适当的unit testing,就像那一列没有被保留可能不成问题。

埃里克,你死了。 对于任何真正可扩展/容易维护/强大的应用程序,唯一真正的答案是免除所有的垃圾和坚持基本。

我跟着我的职业生涯走过了一条类似的轨迹,并得出了相同的结论。 当然,我们被认为是异教徒,看起来很有趣。 但我的东西工作,运作良好。

应该怀疑每行代码。

我想用一个类似于你提出的例子来回答。

在我的公司,我不得不为产品build立一个简单的CRUD部分,我build立了我所有的实体和一个单独的DAL。 后来另一位开发人员不得不改变一个相关的表,他甚至重命名了几个字段。 为了更新我的表单,唯一需要更改的文件是该表的DAL。

(在我看来)实体给一个项目带来的是:

Ortogonality:一层中的变化可能不会影响其他层(当然,如果你对数据库进行了巨大的改变,它会影响所有的层,但是大部分的改变不会)。

可testing性:您可以在不触及数据库的情况下testing您的逻辑。 这增加了testing的性能(允许您更频繁地运行它们)。

分离问题:在一个大产品中,你可以把数据库分配给DBA,他可以优化它。 将模型分配给具有devise必要知识的业务专家。 将单个表单分配给更有经验的webforms等等。

最后我想补充一点,大多数ORM映射器都支持存储过程,因为这就是你正在使用的。

干杯。

我觉得在这个话题上你可能会“咬牙切齿”。 特德·纽纳德(Ted Neward)称他为“ 计算机科学的越南 ”时,并不是轻浮的。

我可以绝对保证的一件事是,在这个问题上它将改变任何人的观点,在无数其他的博客,论坛,播客等中经常被certificate。

对一个有争议的话题进行公开的辩论和辩论当然是可以的,只是这个已经做了很多次了,双方都同意不同意,并且开始编写软件。

如果您想进一步阅读双方,请参阅泰德博客Ayende Rahein,Jimmy Nilson,Scott Bellware,Alt.Net,Stephen Forte,Eric Evans等文章。

@丹,对不起,这不是我要找的东西。 我知道这个理论。 你的陈述“是一个非常糟糕的主意”,没有一个真实的例子。 我们试图用更less的时间,更less的人,更less的错误来开发软件,我们希望能够轻松地进行修改。 根据我的经验,您的多层模型对所有上述类别都是负面的。 特别是关于使数据模型成为最后一件事。 物理数据模型必须从第一天开始考虑。

我发现你的问题真的很有趣。
通常我需要实体对象来封装应用程序的业务逻辑。 把这个逻辑推入数据层是非常复杂和不充分的。
你会做什么来避免这些实体对象? 你有什么解决scheme?

实体对象可以促进应用程序层上的caching。 祝你好运caching一个datareader。

我们也应该谈论这个概念究竟是什么实体。 当我读完这个讨论时,我觉得这里的大多数人都在关注贫血域模型的意义上的实体。 很多人正在将贫血域模型视为反模式!

丰富的领域模型是有价值的。 这就是域驱动devise的全部内容。 我个人认为面向对象是一种克服复杂性的方法。 这不仅意味着技术上的复杂性(如数据访问,UI绑定,安全性) ,还意味着业务领域的复杂性

如果我们可以应用面向对象技术来分析,build模,devise和实现我们的业务问题,这对于非平凡应用程序的可维护性和可扩展性来说是一个巨大的优势!

你的实体和你的表之间有区别。 实体应该代表你的模型,表格只代表你的模型的数据方面!

数据寿命确实比应用程序寿命长,但请考虑一下 David Laribee的 这句话 :模型是永远的……数据是一个快乐的副作用。

有关此主题的更多链接:

  • 为什么Setters和Getters是邪恶的

  • 纯粹的OO的回报

  • POJO与NOJO

  • 超级模型第2部分

  • TDD,模拟和devise

真的很有趣的问题。 老实说,我不能certificate为什么实体是好的。 但我可以分享我的意见,为什么我喜欢他们。 代码如

void exportOrder(Order order, String fileName){...}; 

并不关心从哪里下订单 – 从数据库,从Web请求,从unit testing等等。它使这个方法更明确地声明它需要什么,而不是采取DataRow和logging哪些列,它期望拥有哪些types,他们应该是。 如果以某种方式作为存储过程实现它,同样适用 – 您仍然需要将loggingID推送到它,而不必在DB中存在。

这个方法的实现将基于Order抽象来完成,而不是基于它在数据库中的显示方式。 我实现的大部分这样的操作并不取决于这些数据的存储方式。 我明白一些操作需要与数据库结构耦合以实现性能和可扩展性,就我的经验而言,并不是太多。 根据我的经验,知道Person有.getFirstName()返回String和.getAddress()返回Address,地址有.getZipCode()等等 – 并且不关心哪个表被调用来存储这些数据。

如果你必须处理你所描述的问题,比如当额外的列中断报告性能时,那么对于你的任务DB是一个关键部分,你应该尽可能的接近它。 虽然实体可以提供一些方便的抽象,但它们也可以隐藏一些重要的细节。

可伸缩性在这里很有意思 – 大多数需要巨大可伸缩性的网站(如facebook,livejournal,flickr)倾向于使用DB-ascetic方法,当DB使用尽可能less时,可伸缩性问题可以通过caching(尤其是RAM使用)解决。 http://highscalability.com/有一些有趣的文章。;

除了抽象和松散耦合之外,还有其他很多的实体对象。 我最喜欢的事情之一是使用DataReader或DataTable无法实现的强types。 另一个原因是,如果做得好,适当的实体类可以使代码更加可靠,通过使用特定于领域的术语的第一类结构,任何查看代码的人都可能理解,而不是使用字段名称的一串string为DataRowbuild立索引。 存储过程与使用ORM确实是正交的,因为大量的映射框架使您能够映射到sprocs。

我不会考虑使用sprocs + datareaders替代一个好的ORM。 使用存储过程,您仍受到过程的types签名的约束,并且与过程的types签名紧密耦合,该签名使用与调用代码不同的types系统。 可以对存储过程进行修改,以便修改其他选项和模式更改。 在模式可能发生变化的情况下,存储过程的替代方法是使用视图 – 您可以将对象映射到视图,然后在更改视图时将视图重新映射到基础表。

如果您的经验主要由Java EE和CSLA组成,我可以理解您对ORM的厌恶。 您可能想看看LINQ to SQL,这是一个非常轻量级的框架,主要是与数据库表的一对一映射,但通常只需要稍微扩展就可以成为完整的业务对象。 LINQ to SQL还可以将input和输出对象映射到存储过程的参数和结果。

ADO.NETentity framework还具有以下优点:可以将数据库表视为彼此inheritance的实体类,也可以将多个表中的列合并为一个实体。 如果需要更改模式,则可以更改概念模型到存储模式的映射,而不更改实际的应用程序代码。 再次,存储过程可以在这里使用。

我认为企业中的更多IT项目由于代码的不可维护性或开发人员生产力较差(可能会发生,例如,sproc-writing和app-writing之间的上下文切换)而不是应用程序的可伸缩性问题,从而导致失败。

我还想添加Dan的回答 ,即将这两个模型分开可以使您的应用程序能够在不同的数据库服务器甚至数据库模型上运行。

如果您需要通过负载均衡多个Web服务器来扩展您的应用程序,该怎么办? 您可以在所有Web服务器上安装完整的应用程序,但更好的解决scheme是让Web服务器与应用程序服务器进行通信。

但是,如果没有任何实体对象,他们就不会有太多的话要说。

我不是说如果它是一个简单的,内部的,短暂的生活应用程序,你不应该写巨石。 但是,一旦它变得适度复杂,或者应该持续相当长的时间,你真的需要考虑一个好的devise。

这就节省了维护时间。

通过从表示逻辑和数据访问中分离应用程序逻辑,并在它们之间传递DTO,可以将它们解耦。 允许他们独立地改变。

你可能会发现这篇文章comp.object有趣。

我并不是说同意或不同意,但是这个问题很有意思(我认为)与这个主题有关。

一个问题: 如果所有业务逻辑都被困在数据库中,那么如何处理断开连接的应用程序?

在我感兴趣的企业应用程序types中,我们必须处理多个站点,其中一些必须能够以断开连接的状态运行。
如果你的业务逻辑被封装在一个Domain层中,这个Domain层很容易并入不同的应用程序types,那么我可以build立一些应用程序来了解业务规则,并在必要时能够在本地应用它们。

为了保持数据库存储过程中的域图层,您必须使用一种types的应用程序,该应用程序需要数据库的永久视线。

对于某种types的环境来说没关系,但是它肯定不能涵盖所有的企业应用程序

@jdecuyper,我经常对自己说的一句格言是“如果你的业务逻辑不在你的数据库中,那只是一个build议”。 我想保罗·尼尔森在他的一本书里说过。 应用程序层和UI来来往往,但数据通常生活很长一段时间。

我如何避免实体对象? 存储过程大多数。 我也坦率地承认,无论您是否愿意,业务逻辑都倾向于覆盖应用程序中的所有层。 一定量的耦合是固有的,不可避免的。

最近我一直在思考这个问题, 我曾经是CSLA的一个沉重的用户,我喜欢纯粹的说“所有的业务逻辑(或者至less尽可能多的合理的可能性)都被封装在商业实体中”。

我已经看到,在数据库的devise与使用数据的方式不同的情况下,业务实体模型提供了很大的价值,在很多商业软件中都是如此。

例如,“客户”的概念可以包括客户表中的主要logging,结合客户所下的所有订单,以及所有客户的员工和他们的联系信息,以及一些顾客及其子女可以从查询表中确定。 从开发的angular度来看,能够将客户作为一个单独的实体工作是非常好的,因为从业务angular度来看,客户的概念包含了所有这些东西,并且这些关系可能会或可能不会在数据库中实施。

虽然我很欣赏“如果你的业务规则不在你的数据库中,这只是一个build议”,我也相信你不应该devise数据库来强制业务规则,你应该devise它是有效的,快速和标准化。

也就是说,正如其他人所指出的那样,没有“完美的devise”,工具必须适合这项工作。 但是,使用业务实体可以真正帮助维护和生产力,因为您知道如何去修改业务逻辑,而对象可以以直观的方式build模现实世界的概念。

埃里克,

没有人阻止你select你所期望的框架/方法。 如果你要去“数据驱动/存储过程驱动”的path,那么一定要去! 特别是如果真的,真的可以帮助您按规定准时交付您的应用程序。

警告(对你的问题是一个反面),你的所有业务规则应该在存储过程,你的应用程序只不过是一个瘦客户端。

也就是说,如果你在OOP中做你的应用程序,同样的规则也适用:一致。 遵循OOP的原则,包括创build实体对象来表示您的领域模型。

这里唯一真正的规则是一致性一词。 没有人阻止你走以数据库为中心。 没有人阻止你做旧式结构化(又名,function/程序)程序。 地狱,没有人阻止任何人做COBOL风格的代码。 但是如果希望获得某种程度的成功,那么一旦申请成功,申请必须非常非常一致。

我真的不知道你认为“企业应用程序”。 但是我得到的印象是你将它定义为一个内部应用程序,其中关系型数据库将被设置在一个固定的位置,系统不必与任何其他系统(无论是内部的还是外部的)互操作。

但是如果你的数据库有100个表,相当于每个表的4个存储过程,那么对于基本的CRUD操作,400个存储过程需要维护,而且不是强types的,所以容易出错,也不能被unit testing。 当你得到一个新的CTO谁是开源的传播者,并希望将RDBMS从SQL Server更改为MySql时会发生什么?

现在很多软件,无论是企业应用程序还是产品都在使用SOA,并且有一些暴露Web服务的要求,至less是我所参与的软件。 使用你的方法,你最终将暴露一个序列化的DataTable或DataRows。 现在,如果客户端保证是.NET并且在内部networking上,这可能被认为是可以接受的。 但是,当客户端不知道的时候,你应该努力devise一个直观的API,而且在大多数情况下你不希望暴露全数据库模式。 我当然不想向Java开发人员解释DataTable是什么以及如何使用它。 还有Bandwith和有效负载大小和序列化数据表的考虑,数据集非常重。

没有软件devise的灵丹妙药,它确实取决于优先级在哪里,对我来说它是在unit testing代码和松散耦合的组件,可以容易地消费任何客户端。

只是我2美分

我想为OO和RDB之间的距离问题提供另一个angular度:历史。

任何软件都有一个现实的模型,在某种程度上是对现实的抽象。 没有一个计算机程序能够捕捉现实的所有复杂性,程序的编写只是为了解决现实中的一系列问题。 因此,任何软件模型都是减less现实。 有时候软件模型会迫使现实自我缩小。 就像当你想要汽车租赁公司为你保留任何汽车,只要它是蓝色的,并有合金,但操作员不能遵守,因为你的要求将不适合在电脑。

RDB来自将信息放入表格的非常古老的传统,称为会计。 会计是在纸上完成,然后在打卡上,然后在电脑上完成。 但会计已经是现实的减less。 会计迫使人们长期遵循其制度,以至于已经成为公认的现实。 这就是为什么计算机软件相对容易计算,会计已经有了它的信息模型,早在计算机出现之前。

鉴于良好的会计制度的重要性,以及从任何业务经理的接受度,这些系统已经变得非常先进。 数据库的基础现在非常稳固,没有人会犹豫如何将重要的数据保存在一个值得信任的事情中。

我认为,当人们发现现实的其他方面比会计(这已经是一种模式)更难模型化时,OO一定会出现。 OO已经成为一个非常成功的想法,但是面向对象数据的持久性相对不足。 RDB /会计很容易获胜,但面向对象是一个更大的领域(基本上所有不是会计)。

我们很多人都想要使用面向对象,但我们仍然希望安全地存储我们的数据。 比尊重会计系统存储数据更安全吗? 这是一个诱人的前景,但我们都陷入了同样的陷阱。 与RDB行业的大力推行相比,很less有人想到面向对象的持久性,而RDB行业已经受益于会计的传统和地位。

Prevayler和db4o是一些build议,我确定还有其他的我没有听说过,但似乎没有一个像新闻一样,例如冬眠。

对于多用户应用程序,特别是Web应用程序,将对象存储在优秀的旧文件中似乎并没有被认真对待。

在我每天为了closuresOO和RDB之间的鸿沟而进行的斗争中,尽可能地使用了OO,但是尽可能地减less了inheritance。 我不经常使用SP。 我只会在看起来像会计的方面使用高级查询的东西。

当峡谷closures好时,我会很高兴地恳求。 我认为当Oracle启动类似“Oracle对象实例库”的解决scheme时就会出现。 要真正了解,它必须有一个令人放心的名字。

现在不是很多时间,但只是我的头顶…

实体模型允许您为数据库(和其他可能的系统)提供一致的接口,甚至超出存储过程接口的function。 通过使用企业级业务模型,您可以确保所有应用程序始终如一地影响数据,这是非常重要的事情。 否则,你会得到不好的数据,这是非常邪恶的。

如果你只有一个应用程序,那么你真的没有一个“企业”系统,不pipe这个应用程序或你的数据有多大。 在这种情况下,您可以使用类似于您所谈论的方法。 如果您决定在未来发展您的系统,请注意您将需要做的工作。

以下是您应该记住的一些事项(IMO):

  1. 生成的SQL代码是不好的(例外)。 对不起,我知道很多人认为这是一个非常节省时间的方法,但是我从来没有发现一个系统可以产生比我写的代码更高效的代码,而且这个代码通常很糟糕。 您通常最终还是会生成大量永远无法使用的SQL代码。 这里的例外是很简单的模式,比如查找表。 尽pipe如此,很多人都被这个问题搞得一团糟。
  2. 实体<>表(甚至必然是逻辑数据模型实体)。 数据模型通常具有数据规则,这些规则应尽可能地与数据库保持一致,这些规则可以包括关于表格行之间的相互关系的规则或者对于声明性RI来说太复杂的其他类似规则。 这些应该在存储过程中处理。 如果你所有的存储过程都是简单的CRUD过程,那么你不能这么做。 最重要的是,CRUD模型通常会产生性能问题,因为它不会最小化networking到数据库的往返行程。 这往往是企业应用程序中最大的瓶颈。

有时候,你的应用程序和数据层不是那么紧密耦合的。 例如,您可能有一个电话帐单应用程序。 您以后创build一个单独的应用程序,监视电话使用a)更好地为您做广告b)优化您的电话计划。

这些应用程序有不同的关注点和数据需求(即使数据来自同一个数据库),它们将驱动不同的devise。 如果让数据库驱动代码,您的代码库可能会造成绝对的混乱(在任一应用程序中),并且会导致恶意的维护。

具有与数据存储逻辑分离的域逻辑的应用程序适用于任何types的数据源(数据库或其他)或UI(Web或Windows(或Linux等))应用程序。

你几乎呆在你的数据库中,如果你对一个对你使用的当前数据库系统感到满意的公司,这并不坏。 但是,由于数据库会随着时间的推移而加速,所以可能会有一个新的数据库系统。 如果他们想要切换到数据访问的Web服务方法(如面向服务的体系结构),该怎么办? 您可能需要将存储过程移到所有位置。

此外,域逻辑抽象出用户界面,这对于大型复杂系统中不断发展的用户界面(尤其是在不断寻找更多客户的情况下)可能更为重要。

另外,虽然我同意存储过程和域逻辑问题没有明确的答案。 我在域逻辑阵营(我认为他们正在赢得一段时间),因为我相信精心制作的存储过程比精巧的域逻辑难以维护。 但这是另外一个辩论

我认为你只是习惯于编写一个特定types的应用程序,并解决某种问题。 你似乎是从“数据库第一”的angular度来攻击这个问题。 有很多开发人员将数据保存到数据库,但性能不是最重要的。 在很多情况下,对持久层进行抽象化大大简化了代码,而且性能成本也不是问题。

不pipe你在做什么,这不是OOP。 这没有错,只是不是面向对象,将解决scheme应用于其他所有问题是没有意义的。

有趣的问题。 一些想法:

  1. 如果你所有的业务逻辑都在你的数据库中,你将如何testing?
  2. 不会更改您的数据库结构,特别是影响您的应用程序中的多个页面的结构,是整个应用程序更改的主要麻烦?

好问题!

我更喜欢的一种方法是创build一个迭代器/生成器对象,它发出与特定上下文相关的对象的实例。 通常这个对象包装了一些底层数据库访问的东西,但是在使用它的时候我不需要知道。

例如,

一个AnswerIterator对象生成AnswerIterator.Answer对象。 在引擎盖下,它遍历一个SQL语句来获取所有的答案,另一个SQL语句来获取所有相关的注释。 但是,当使用迭代器时,我只是使用具有此上下文的最小属性的Answer对象。 随着一点点的骨架代码,这几乎变得微不足道。

我已经发现,当我有一个巨大的数据集来处理时,这个效果很好,而且如果做得好的话,它给了我相对容易testing的小型瞬态对象。

它基本上是一个在数据库访问的东西薄单板,但它仍然给我的抽象的时候,我需要的灵活性。

我的应用程序中的对象倾向于与数据库一对一地关联,但是我发现使用Linq To Sql而不是sprocs使编写复杂查询变得容易,特别是能够使用延迟执行来构build它们。 例如从Images.User.Ratings中的r等等。这样可以节省我试图在sql中计算出几个连接语句,而Skip&Take分页也简化了代码,而不是embeddedrow_number和'over'代码。

为什么停在实体对象? 如果您在企业级应用程序中看不到实体对象的价值,那么只需以纯粹的function/过程语言进行数据访问,然后将其连接到UI。 为什么不把所有的OO“绒毛”都剪掉?