NHibernate真的是“透明的”,正如维基百科所说的那样吗?

时间:2013-10-23 17:55:17

标签: c# .net nhibernate

Wikipedia上,我读到了:

  

NHibernate为普通旧CLR对象(PO​​CO)提供透明持久性。

在我的世界中,这意味着我不必在我的类中更改我的代码,因此我不必向属性添加属性,也不必继承超类或实现接口。

在我的世界里,它也意味着“引擎”,在这种情况下是NHibernate,负责读取类并将它们“无缝地”保存在数据库中。

但是当我在NHibernates网页上阅读时,我认为它根本不透明。所以,我的问题是,如果这些陈述是正确的,或者我错过了什么:

  • 选项1:您必须为解决方案中的每个类创建一个令人讨厌的.hbm.xml文件link
  • 选项2:使用Fluent NHibernate,您必须为解决方案中的每个类创建一个单独的地图类,并在PersistenceModel类中保留我的类列表({{ 3}})

这是真的吗?

因为如果是的话,这远非“透明”。正如我所看到的那样,尝试在已经存在的项目中切换到NHibernate,地狱,因为它涉及编写数百个XML文件,然后在类更改时更新这些XML文件,或创建数百个映射类并将其更新为真正的班级改变了。

我说得对吗?

4 个答案:

答案 0 :(得分:3)

提到的透明度并不是指简单的配置,而是对域模型的最小化改变。当然,它引入了对您的域模型的一些要求,但无论如何我认为这些要求是良好的做法。

  • 必须存在无参数构造函数。它可能受到保护,因此不会被正常代码隐藏。
  • 必须将所有方法和属性声明为虚拟。 (这可能只是不同代理解决方案和延迟加载的要求。)

我认为这两点是正确的解决方案,因为派生类可能想要覆盖我的任何东西以改变行为或引入检查是合法的。他们应该能够做到这一点。

对于您打算使用的每个实体类型,您将需要一个hbm-xml-configuration-element(它们可以存储在一个大型xml文件中)。流畅的NHibernate并不神奇,但会在内存中生成那些NHibernate使用的配置条目。如果您想避免使用类映射,可以使用Fluent NHibernate conventions

答案 1 :(得分:1)

就“透明”而言,这有些主观,但期望在

范围内进行操作
using( ISession s = sessionFactory.OpenSession()){
    using( ITransaction t = s.BeginTransaction()){
        // do some work
        t.Commit();
    }
}

如果您想要进行任何类型的会话缓存。此外,操作不应跨越事务。

至于必须“创建数百个XML文件” - 有一些工具可以从现有模式生成映射。

https://www.google.com/#q=nhibernate+mapping+generator

答案 2 :(得分:1)

我认为透明度要高于你所提出的要求。 我认为NHibernate与任何ORM一样透明。 我认为ORM不可能真正透明。

当我读到它时,你对“透明”的定义是:

  • 不必更改课程中的代码,特别是......
    • 不必向属性添加属性
    • 不必从超类继承
    • 不必实现接口
  • ORM照顾...
    • “无缝地”从数据库中读取类
    • “无缝地”持久保存数据库中的类

根据这个定义,NHibernate传递着绚丽的色彩。 映射存储在域类的外部,因此您的域类可以完全忽略这样一个属性存储在哪个特定列中的事实。 可以选择来使用属性在您的类中存储映射,但您不必这样做。

您不必为您的域类使用任何特定的基类或接口。 正如Simon Svensson所提到的,NHibernate不需要基类,而是需要将类的所有成员声明为virtual。 这是必需的,以便NHibernate可以将延迟加载行为注入到您的类中。

就ORM无缝读取和持久化对象而言,我认为这是非常无缝的,就像我想要的那样无缝:

var customer = session.Get<Customer>(42);
customer.Email = "example@example.com";
customer.Addresses.Remove("Home");
session.SaveOrUpdate(customer);

比这更加无缝,我们开始冒险进入令人毛骨悚然的思维阅读代码。

但是,我认为上述“透明”的定义并不完整。 我希望ORM提供“透明持久性”,允许我编写我的域类,就像我在.NET中自然编写的那样,充分利用不同类型的集合,如字典和集合,利用继承和多态,枚举等。 我希望能够操纵多对多关系而不必被迫通过中间类隧道只是因为它更密切地模拟了关系数据库的工作方式。 NHibernate也通过了所有这些颜色。

但这些东西需要映射。 否则,别无选择,只能将您限制为最接近表和列的面向对象设计元素的子集。 因此,可能需要映射的事实是减号,但它会带来更大的优势。

我是第二个Simon Svensson的建议,你再看看Fluent NHibernate。 假设您的数据库模式和对象模型以一致,合理的方式构建,您可以使用FluentNH的Auto Mapping来大大减少您必须执行的手动映射的数量,并且在某些地方只需override它根据需要。

至于维基百科使用术语“透明”是否公平,这听起来更像是Wikipedia Talk page的讨论,而不是StackOverflow。 在我看来,它是close enough description for an encyclopedia。 即使glass isn't 100% transparent,我们仍然是call it transparent

如果您需要比ORM提供的透明度更高的透明度,您可以尝试查看文档数据库。与对象相比,文档与对象的相似性要大得多。

答案 3 :(得分:0)

不,你没有做对。

NHibernate和其他几个ORM,旨在简化您的开发过程。

它有很多好处,它为您提供了一层抽象,可测试性和可重用性。

我不明白为什么你抱怨配置..

EF首先有代码。最小的配置,它不能比这更好。

我曾在一家公司工作,那里有成千上万的开发人员,并不是所有人都知道oracle进出。但是通过像抽象这样的休眠,他们可以轻松完成工作。