ORM仓储模式

3
这更像是一个征求意见的问题。我正在处理一个同时使用NHibernate和EntityFramework的项目(这是有意为之,因为我需要灵活性)。所以,我开始着手开发一个仓储模式,但遇到了一个小问题。
基本上,我想知道你们对以下几个方面的看法:
1. 仓储应该是单例吗?- 这将使我保持会话打开状态,但同时,我认为它会保持与数据库的连接打开。对于NHibernate,ORM只能保证对象在同一会话中是相同的。这对于简单编码来说是理想的,但可以通过键和重写GetHashCode和Equals方法来克服这个问题。 2. 如果它不是单例(甚至如果它是),我应该在使用后立即关闭连接吗?对于NHibernate,这意味着每次"处理"仓储后都要关闭会话。 3. 你是否已经为NHibernate或EF 4.0实现了仓储模式并找到了有用的想法?

3
很明显,这个话题是切题的,我不确定谁会如此虚伪地投票说它不是。@John Saunders,你在挑剔用词。你有C#的EMCA语言规范,然后你有C#.NET,它是C#的标准视图,包括所有.NET的功能和原始语言本身。 - Chris Marisic
@Chris:我觉得这个帖子应该移到程序员版块,那里更适合主观讨论。 - John Saunders
我是为那些想要了解这个主题的人而设计的,以便他们理解我在一个.NET平台上针对C#应用程序的功能。 我也暗示C#就是.NET,但正如Chris所说...我只是想让它更清楚,C#或.NET的人可以查看这个,因为我也能够理解VB.NET的例子... - John
我猜标题“离题讨论”本身就是不诚实的,如果你不点击它查看为什么显示为离题讨论,那么在SO与程序员之间进行比较时。 - Chris Marisic
请查看此文章:http://bit.ly/bF7jL3。它描述了如何将O / RM隐藏在工作单元和存储库后,同时仍然允许在其上进行LINQ查询。这可能会给您一些方向。 - Steven
显示剩余2条评论
2个回答

4
不要自己编写单例模式的创建(即单例模式本身),使用IOC框架(如StructureMap)来处理对象的生命周期管理。
1.我们无法回答这个问题。如果它是单例模式,则必须针对其内部管理的资源(如DB实时连接的连接池)进行线程安全。线程安全的代码并不是简单的。
2.我们无法回答这个问题。它取决于您如何操作您的模型。这还取决于您是否希望人们能够通过DataReader读取需要与数据库保持活动连接的内容。这也会影响诸如惰性加载之类的事情,这需要活动会话,这在数据绑定中变成了一场噩梦。
3.以下是我为NH创建存储库模式所想到的所有内容:Creating a common generic and extensible NHiberate Repository version 2

看了你网站上的示例,似乎你的存储库与nhibernate紧密相关。我的则更为通用,只提供Save/Delete/ToQueryable。至于单例和线程安全难度大的问题,这不仅仅是在执行任何可能不安全的非线程操作之前锁定静态对象就可以解决吗? - John
1
锁定的复杂程度取决于您需要保护的资源之间的关系。我并没有特别说它很难,只是不太平凡。线程永远不是平凡的。也要记住锁定的目的,通过强制单线程访问使其线程安全可能会变得非常容易,其中每个消费者都必须等待前一个消费者的请求完成;) 关于“更通用”存储库的概念,在我的评论中有讨论。我认为这是毫无意义的。 - Chris Marisic
1
如果我真的必须创建另一层抽象,我会创建一个包装器来包装我的存储库使用。在你到达虚无之前,你只能抽象出那么多东西。或者说,你需要创建一个完整的元DSL来查询对象,然后将其转换为ORM最深处的实际工作代码/SQL。如果你认真对待这个问题,我会从DetachedCriterion模式开始,然后构建新的条件->数据库代码转换器(或者至少利用NH的代码直接转换为SQL)。 - Chris Marisic

0
第一个问题,它必须使用NHibernate吗?为什么不考虑使用带有IoC的EF4,我最喜欢的是StructureMap,然后您就不必担心使存储库成为单例,因为StructureMap提供了按请求、按HttpContext、按混合方式保持范围开放的选项。当然,您可以选择使用Singleton模式与您的Repository,但我认为在这种情况下不是可行的选项。
希望这比让您感到困惑更有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接