使用 POCO 进行延迟加载的存储库模式
Posted
技术标签:
【中文标题】使用 POCO 进行延迟加载的存储库模式【英文标题】:Repository pattern with lazying loading using POCO 【发布时间】:2011-02-05 15:19:15 【问题描述】:我正在开始一个新项目并创建业务对象和数据访问等。我只是使用普通的旧 clr 对象而不是任何 orms。我创建了两个类库: 1)业务对象 - 包含我所有的业务对象,所有这些对象都是轻量级的,只有属性和业务规则。 2) 存储库 - 这是我所有的数据访问。
我的大多数对象都会包含子列表,我的问题是延迟加载这些值的最佳方法是什么,因为我不想在不需要时带回不必要的信息。
我考虑过在子属性上使用“get”来检查它是否为“null”以及是否调用我的存储库来获取子信息。据我所知,这有两个问题: 1)对象“知道”如何获取自己我宁愿没有数据访问逻辑保存在对象中。 2) 这需要两个类相互引用,这在 Visual Studio 中会引发循环依赖错误。
是否有人对如何克服此问题或对我的项目布局以及可以改进的地方有任何建议?
谢谢
【问题讨论】:
【参考方案1】:为此,您需要对接口进行编程(实现上的抽象)和/或将您的属性声明为虚拟。然后,您的存储库为要延迟加载的那些属性返回一个代理对象。调用存储库的类并不明智,但是当它尝试访问其中一个属性时,代理会调用数据库并加载值。
坦率地说,我认为自己尝试实现这一点很疯狂。对于这个问题,有很多经过时间考验的出色解决方案,由 .NET 领域最伟大的人开发和完善。
要进行代理,您可以使用Castle DynamicProxy,或者您可以使用NHibernate 并让它为您处理所有代理和延迟加载(它使用DynamicProxy)。保证您将获得比任何手动实现更好的性能。
NHibernate 不会弄乱你的 POCO——没有属性,没有基类;您只需要将成员标记为虚拟以允许生成代理。
简单地说,我会重新考虑使用 ORM,特别是如果您想要延迟加载;您不必放弃 POCO。
【讨论】:
【参考方案2】:在查看提供的答案并进一步研究后,我发现了一篇使用委托进行延迟加载的文章。这提供了一个比使用代理或实现 NHibernate 更简单的解决方案。
这是文章的link。
【讨论】:
【参考方案3】:如果您使用的是 Entity Framework 4.0,您将获得对具有延迟加载的 POCO 的支持,并且将允许您编写一个通用存储库来进行数据访问。
网上有大量关于 EF 4.0 通用存储库模式的文章
HTH。
【讨论】:
【参考方案4】:如果您的延迟加载代码在运行时加载存储库(Activator.CreateInstance 或类似的东西),然后通过反射调用适当的方法,您可以绕过循环依赖问题。当然,反射会带来性能损失,但在大多数解决方案中往往是微不足道的。
解决此问题的另一种方法是简单地编译为单个 dll - 在这里您仍然可以使用不同的命名空间在逻辑上分离您的层,并且仍然可以使用不同的目录来组织您的类。
【讨论】:
以上是关于使用 POCO 进行延迟加载的存储库模式的主要内容,如果未能解决你的问题,请参考以下文章