我想要一个ORM吗?

时间:2011-03-03 07:41:18

标签: c# nhibernate orm linq-to-xml sql-server-ce

我们在三个应用程序中使用了一个对象模型。两个程序收集数据,另一个程序读取数据并生成报告。系统非常断开连接,因此我们不能让所有程序都与单个数据库通信。

现在,程序只使用公共库来填充对象模型并序列化/反序列化到磁盘。具体来说,我们正在使用XML序列化。

此型号存在一些问题。 1)XML可能被认为是浪费。文件可能变得庞大而且难以处理。老实说,文件大小现在不是一个大问题。 2)我最关心的是记忆足印。整个文件被加载到对象模型中,然后进行操作,然后保存。

希望我已经表达了我的担心,在某些时候我们会在运行时遇到此应用程序的内存问题。足够的数据将被收集到一个“数据库”(xml文件)中,无法一次性加载到内存中。

我想要的是访问由文件存储而不是内存支持的对象模型。我希望对象模型的更改最小化。当访问一个对象时,它来自磁盘,当它被设置时,它被保存(如果可能的话,自动保存)。

我们已经使用SQLite,SQL Compact 4.0和EF 4以及LINQ to XML(简要地)研究了NHibernate。我过去也使用db4o将对象缓存到磁盘,但这是一个不相关的项目。

在我潜入并投入时间学习其中之一之前,我想知道我的想法是否有意义。我是否可以拥有一个“神奇地”缓存到存储介质的对象模型,而不是无限地膨胀我的内存占用?即使它不是最优雅的,最简单的方法是什么?

是否有其他技术可以帮助我?内存映射文件,linq-to-sql,Lazy(T)(仅用于在需要时从文件中提取对象)。

我意识到这是一个开放式的问题。我正在寻找一个大图片响应和详细信息,如果有人有真实的世界经验这样做。链接会有所帮助......

感谢。

3 个答案:

答案 0 :(得分:6)

是的,ORM将对象模型映射到关系模型。他们非常好地隐藏了读取和写入数据到数据库,缓存数据,管理内存等所有的管道工作。他们也非常能够缓存对象图的一部分,并且可以做一些事情来提高性能例如延迟加载数据。

答案 1 :(得分:4)

我刚刚完成了将由XML文件支持的(主要是“继承的”)Web应用程序迁移到NHibernate,完全出于同样的考虑。我也处于以前从未使用过NHibernate并希望在此过程中学习的情况。 这个想法确实有意义。您确实可以在内存中加载您实际需要的部分(而不是整个数据库)以及比这更多的好处。

基于您要求的其他内容(对象模型的最小更改,易于从实际应用程序迁移到基于ORM的应用程序)我不确定您是否会如此轻松地获取它们。 对于像NHibernate和EF4这样的ORM,模型类非常轻量级:它们基本上只是属性容器。基于XML文件的应用程序倾向于在模型中直接拥有更多逻辑:您可能必须转移到数据访问层的逻辑。重新设计模型和数据访问层可能是您将面临的最耗时的任务。我知道这是给我的。

我从你的问题中推断的另一件事(你说你不能让所有三个程序都在同一个DB上,而你提到SQLite和SQL Compact)是你通过复制文件在三个应用程序中复制数据物理。您如何检测更改以及您需要3个数据库的对齐方式?您目前如何合并更改(如果您拥有3个应用程序中的2个可以写入数据)? 根据您复制数据的方式,ORM可能会或可能不会帮助您。

根据您的评论修改更多积分

  • 如果您希望在某个时刻将文件合并到一个数据库中并且您还不确定它是否是Microsoft产品,那么NHibernate是最佳选择。但是如果你现在广泛使用LINQ(根据你的另一个评论)并希望更加无缝的转换我会选择EF4:Nhibernate.Linq并不是真正完整的,而且有些构造不起作用。
  • NHibernate和EF4都有很好的文档,并且提供了很好的教程,介绍如何从头开始构建一个完整的应用程序,因此学习部分非常简单。
  • 两者都有一个“模型优先”的方法,你可以根据你的模型类获得一个为你创建数据库的工具,所以如果你的模型类非常轻量级,你应该可以很少修改它们。
  • 在NHibernate中花了我一些时间(有时候我仍然很难工作)的事情是配置级联以按照我的预期行事:例如删除对象时“相关”对象会发生什么?

答案 2 :(得分:1)

我的建议是您使用文档数据库。 RavenDB会给你带来很多好处。您可以存储对象而无需将它们转换为关系模型,就像db4o那样。

但是,使用RavenDB,您可以使用Map / Reduce查询数据。另一个好处是它是使用.NET for .NET编写的,因此您将享受在Linq中查询。它可以作为Windows服务运行,也可以在IIS中运行。它也可以运行嵌入式,非常适合测试目的。对于您的数据收集应用程序来说,这可能是个好主意。

RavenDB还支持复制,因此您可以将数据存储在一个实例中并将其复制到另一个实例中。也许这可以解决您的分布式设置。

但是,根据您的分布式设置的性质,我认为您最好使用服务总线。您是否需要在数据收集应用程序中使用状态?如果没有,只需发布​​一条消息,其中包含服务总线上的数据,供系统的另一部分使用。听起来可能很复杂,但事实并非如此。看看nServicebus