Poco与ORM有什么“大”优势?

我想到的一个优点是,如果你使用Poco类进行Orm映射,如果两者都支持Poco,你可以轻松地从一个ORM切换到另一个ORM。

拥有一个没有Poco支持的ORM,例如使用像DataObjects.Net Orm这样的属性进行映射对我来说不是问题,对于Poco支持的Orms及其生成的代理实体,您必须知道实体实际上是绑定到某些上下文/会话的DAO对象,例如序列化是一个问题,等等。

POCO就是松散耦合和可测试性。

因此,当您进行POCO时,您可以单独测试您的域模型(如果您正在进行DDD)。 您不必担心它是如何持久存在的。 您不需要存根上下文/会话来测试您的域。

另一个优点是泄漏抽象较少。 因为持久性问题不会被推送到域层。 所以你正在执行SRP原则。

我可以看到的第三个优势是,POCO你的领域模型更具有进化性和灵活性。 与连接到持久性的function相比,您可以更轻松地添加新function。

我在做DDD时使用POCO,但是对于某种应用程序,你不需要做DDD(如果你正在做基于小数据的应用程序),所以问题就不一样了。

希望这可以帮助

没有。 点。 人们喜欢扔的所有优点都是在图片的大规模上不重要的优点。 我更喜欢实体对象的强基类,它实际上拥有大量集成代码(比如在属性更改时抛出属性更改事件),而不是自己编写所有这些内容。 请注意,在“LINQ”或“ObjectSpaces”存在之前,我DID写了一个(当时是商业上可用的)ORM for .NET。 我已经使用了O / R mappers 15年了,而且从来没有发现POCO确实值得遇到麻烦的情况。

也就是说,属性可能因其他原因而变坏。 我现在更喜欢Fluent NHibernate方法 – 使用属性启动了我自己的(现已退役的)映射器,然后转移到基于XML的文件。

“POCO让我一无所有”的主题主要来自实体简单而非正常的对象。 它们具有许多额外的function以及用户应该知道的限制(如查询速度等)。 ORM,尽管LINQ,但无论如何都不可替换 – 如果你开始使用它们真正有趣的更高function的话。 所以,最后你得到了POCO,仍然是一个基类和左右不同的语义。

我发现大多数POCO的支持者(如:“必须有”,而不是“会很好”)通常没有想到他们对真实目的的论证。 你会得到各种非常糟糕的想法,几乎就是“存储过程比动态SQL更快” – 这些东西根本不适用。 像:

  • “我希望在他们不需要保存数据库的情况下使用它们”(使用单独的对象池,永不提交),
  • “我可能希望在基类中拥有自己的function(ORM应该在没有function的情况下分类抽象实体,因此将您的OWN基类放在ORM之下)
  • “我可能想要用另一个替换ORM”(所以永远不要使用任何更高的function,希望ORM API兼容,然后你仍然可能需要重写大部分)。

一般来说,POCO人员也忽视了实际工作量很大的工作量 – 如交易对象更新等等,基类中有一大堆代码。 某些.NET接口在POCO级别上实现起来很恐怖,但如果可以绑定到ORM则要容易得多。

在这里接受Thomas Jaskula的职位:

POCO就是松散耦合和可测试性。

假设你可以在没有它的情况下测试数据绑定? 可测试性是模拟框架的东西,并且真正有力的甚至可以“重定向”方法调用。

因此,当您进行POCO时,您可以单独测试您的域模型(例如,如果您正在进行DDD)。 您不必担心它是如何持久存在的。 您不需要存根上下文/会话来测试您的域。

其实不是真的。 持久性应该是任何域模型测试的一部分,因为域模型是持久存在的。 您总是可以通过不提交更改来测试非持久性方案,但是许多测试将涉及持久性和失败(例如,无效/丢失数据的发票无法写入光盘)。

另一个优点是泄漏抽象较少。 因为持久性问题不会被推送到域层。 所以你正在执行SRP原则。

其实没有。 正确的域模型永远不会在实体中具有持久性方法。 这是一个以(user.Save())开头的垃圾ORM。 OTOH基类将用于validation(IDataErrorInfo),处理持久字段上的属性更新事件,并且通常可以节省大量时间。

正如我之前所说,你应该拥有的一些function实际上很难用变量作为数据存储来实现 – 比如将实体置于更新模式,进行一些更改然后回滚它们的能力。 不需要 – 告诉微软谁在他们的数据网格中使用它(你可以改变一些属性,然后点击转义以回滚更改)。

我可以看到的第三个优势是,POCO你的领域模型更具有进化性和灵活性。 与连接到持久性的function相比,您可以更轻松地添加新function。

非说法。 您无法在不处理持久性的情况下将字段添加到peristet类,并且可以将非持久性function(方法)添加到非poco类,与poco类相同。

通常,我的非POCO基类执行以下操作:

  • 处理属性更新和IDataErrorInfo – 无需用户为ORM可以处理的字段和项编写一行代码。
  • 处理对象状态信息(新建,更新等)。 这是恕我直言的内在信息,也经常被推到用户界面。 请注意,这不是“保存”方法,而只是EntityStatus属性。

它包含了许多可覆盖的方法,实体可以使用这些方法来扩展行为而不实现(公共)接口 – 因此这些方法对于实体来说实际上是私有的。 它还有一些内部属性,比如可以访问负责实体的“对象管理器”,这也是要求其他实体(提交查询)的重点,有时需要这些实体。

根据单一责任原则 ,POCO对ORM的支持就是关注点的分离。 通过POCO支持,ORM可以直接与域模型通信,而无需使用特定于数据访问的代码“混淆”域。 这可确保域模型仅用于解决与域相关的问题,而不是数据访问问题。

除此之外,POCO支持可以更容易地单独测试对象的行为,而无需数据库,映射信息甚至是对ORM程序集的引用。 拥有“独立”对象的能力可以使开发变得更加容易,因为对象很容易实例化并且易于预测。

此外,由于POCO对象不依赖于数据源,因此无论是从主数据库,备用数据库,平面文件还是任何其他进程加载,都可以将它们视为相同。 尽管这似乎不会立即有益,但无论来源如何处理对象都可以使行为易于预测和使用。

我为最近的ORM选择了NHibernate,因为它支持POCO对象,它处理得非常好。 它适合项目遵循的域驱动设计方法,并使数据库和域之间实现了很好的分离。

能够切换ORM工具并不是POCO支持的真正理由。 尽管您的类可能与ORM没有任何直接依赖关系,但它们的行为和形状将受到ORM工具及其映射到的数据库的限制。 更改ORM与更改数据库提供程序一样重要。 在一个ORM中将始终存在其他function不可用的function,您的域类将反映function的可用性或缺失。

在NHibernate中,您需要将所有publicprotected类成员标记为virtual以启用对延迟加载的支持。 这种限制虽然没有显着改变我的域层,但却对其设计产生了影响。