如何在没有数据库持久性的情况下让NHibernate知道一流的“Null对象”?

时间:2009-07-03 08:19:32

标签: nhibernate fluent-nhibernate nhibernate-mapping null-object-pattern

我想在我的域中使用Null对象模式,但我不希望在我的数据库中有与之相关的记录 - 如果NHibernate能够将SQL null值映射到我的Null对象,反之亦然。

这是否可行(使用Fluent NHibernate进行映射)

P.S。这似乎是人们希望解决的一个相当普遍的问题,但我想知道为什么我一直在努力寻找答案。

修改 从这篇博客文章来看,它看起来不像是直接可能的:NHibernate & Null Object Pattern: The Options

3 个答案:

答案 0 :(得分:1)

在不流畅的nhibernate中,您可以使用不会像这样持久存储到数据库的导入映射;

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
      namespace="MyProject.MiddleTier"    
      assembly="MyProject.MiddleTier">
   <import class="ThingNotToPersist"/>
</hibernate-mapping>

不知道这项工作如何流利,但希望它能为你提供一个启动。

答案 1 :(得分:0)

答案是......你做不到。 Oren说“NHibernate的null概念不是你可以轻易改变的东西,而且它不会通过拦截器这样做。你可以使用null对象作为值类型(使用UserType),但不是实体。“

答案 2 :(得分:0)

好的,自从这个问题发布以来,NHibernate 3已经发布了 - 也许现在可能有所作为了吗?

我不愿意放弃这一点 - 我想使用空对象模式,我不会对“你不能”感到满意,所以让我们考虑实现这个目标的方法! / p>

我在网上的几个帖子和笔记中遇到的一个想法是使用两个属性 - 一个具有公共(未映射)和一个具有私有(映射)访问 - 因此公共属性的get-accessor将类似于return MyPrivate ?? MyType.NullObject ...我已经消除了这个想法,因为它会在查询界面上产生问题 - 你无法查询公共属性,因为它没有被映射。所以我们可以忘记这种方法。

我有两个在任何地方都没有看到的想法:

使用拦截器在读/写之前/之后更改属性值。

有人提到拦截器无法正常工作,但请耐心等待......伪代码:

class Foo
{
    public Bar Bar { get; set; }
}

class Bar
{
    public static Bar None;
}

class MyInterceptor
{
    public void AfterLoad(IEntity object)
    {
        foreach (property in object)
            if (property.type == typeof(Bar) && property.value == null)
                object[property].value = Bar.None;
    }

    public void BeforeSave(IEntity object)
    {
        foreach (property in object)
            if (property.type == typeof(Bar) && property.value == Bar.None)
                object[property].value = null;
    }

    public void AfterSave(IEntity object)
    {
        foreach (property in object)
            if (property.type == typeof(Bar) && property.value == null)
                object[property].value = Bar.None;
    }
}

简而言之,在加载时用null-object替换null;在保存之前,用实际的空值替换null-object,并在保存之后,替换回null对象。

使用查询API时,您当然需要查询实际的空值,但如果您在查询API上有某种条件构建器或工厂类,则可以在那里考虑。

将您的类型扩展为专用的空对象类型,并使其成为非持久性类型。不知。

只是一个想法 - 假设您要将类型扩展为专用的null-object-type。有点像:

class Bar
{
    public static NullBar; // instace of NullBar
}

class NullBar : Bar
{
    // ...
}

既然NullBar是一个专用类型扩展Bar,我们能不能告诉NHibernate不要映射Nullar类型,即使它扩展了Bar,它被映射了?

这些是我的想法 - 其中任何一个听起来都合理吗?

(我是一个NHibernate noob,顺便说一句 - 但我坚持不懈,而不是因为你可以救我并将我放在一边等待。)