如何在没有数据库持久性的情况下让 NHibernate 意识到一流的“空对象”?

发布于 2024-07-26 22:06:40 字数 425 浏览 7 评论 0原文

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

这可能吗(使用 Fluent NHibernate 进行映射)

PS 这似乎是人们正在寻求解决的一个相当常见的问题,但我想知道为什么我一直在努力寻找答案。

编辑: 从这篇博客文章来看,它看起来不太可能直接实现:NHibernate & 空对象模式:选项

I would like to make use of the Null Object pattern in my domain, but I don't want to have records in my database that relate to it - I would prefer it if NHibernate were able to map a SQL null value to my Null object, and vice versa.

Is this possible (using Fluent NHibernate for mappings)

P.S. This seems like it is a fairly common issue people are looking to resolve, but I wonder why I have struggled to find an answer.

Edit:
Judging by this blog entry it doesn't look like it's going to be directly possible: NHibernate & Null Object Pattern: The Options

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄荷→糖丶微凉 2024-08-02 22:06:40

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

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

不知道这是如何流畅地工作的,但希望它能为您提供一个入门。

In not fluent nhibernate you can use an Import mapping that will not persist to the database like this;

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

Don't know how this work in fluent but hopefully it gives you a starter.

凡尘雨 2024-08-02 22:06:40

答案是……你不能。 Oren 说“NHibernate 的 null 概念不是您可以轻松更改的东西,并且它不会通过拦截器来实现这一点。您可以将 null 对象用于值类型(使用 UserType),但不适用于实体。”

The answer is... you can't. Oren says "NHibernate's concept of null isn't something that you can easily change, and it doesn't go through an interceptor to do so. You could use null objects for value types (using UserType), but not for entities."

拥抱我好吗 2024-08-02 22:06:40

好吧,既然这个问题被发布了,NHibernate 3 就发布了——也许现在有些事情是可能的?

我不愿意就此放弃——我想使用空对象模式,并且我不会满足于“你不能”,所以让我们考虑一下实现这一目标的方法!

我在网络上的几篇文章和笔记中遇到的一个想法是使用两个属性 - 一个具有公共(未映射)访问权限,另一个具有私有(映射)访问权限 - 因此公共属性的 get-accessor 会是这样的返回 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;
    }
}

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

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

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

只是一个想法 - 假设您要将您的类型扩展为专用的空对象类型。 大致意思是:

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

class NullBar : Bar
{
    // ...
}

现在 NullBar 是扩展 Bar 的专用类型,我们是否可以以某种方式告诉 NHibernate 不要映射 Nullar 类型,即使它扩展了已映射的 Bar?

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

(顺便说一句,我是一个 NHibernate 菜鸟 - 但我很执着,并不是说你可以救我并把我放在一边以供以后使用。)

Okay, since this question was posted, NHibernate 3 was released - maybe something is possible now?

I'm not willing to let this go - I want to use the null-object pattern, and I'm not going to be satisfied with "you can't", so let's think about ways to achieve this!

One idea I've come across in several posts and notes around the web, is to use two properties - one with public (unmapped) and one with private (mapped) access - so the get-accessor for the public property would be something like return MyPrivate ?? MyType.NullObject ... I've eliminated that idea, because it creates problems with the query interface - you can't query on the public property, because it's not mapped. So we can forget that approach.

I have two ideas I have not seen explored anywhere:

Use an interceptor to change the property value before/after read/write.

Someone mentioned an interceptor won't work, but bear with me... in pseudo-code:

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;
    }
}

In short, substitute nulls with the null-object on load; before saving, substitute null-object with an actual null-value, and after saving, substitute back the null-object.

When using the query API, of course you would need to query for actual null-values, but if you have some sort of criteria-builder or factory-class over the query API, you can account for that there.

Extend your type to a dedicated null-object type and make it non-persistent. Somehow.

Just a thought - suppose you were to extend your type into a dedicated null-object-type. Something along the lines of:

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

class NullBar : Bar
{
    // ...
}

Now that NullBar is a dedicated type extending Bar, can we somehow tell NHibernate NOT to map the Nullar type, even though it extends Bar, which is mapped?

Those are my ideas - either of those sound plausible?

(I'm an NHibernate noob, btw - but I'm persistent, and not in the sense that you can save me and set me aside for later.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文