我想在我的域中使用 Null 对象模式,但我不想在我的数据库中有与之相关的记录 - 如果 NHibernate 能够将 SQL 空值映射到我的 Null 对象,我会更喜欢它,反之亦然。
这可能吗(使用 Fluent NHibernate 进行映射)
PS 这似乎是人们希望解决的一个相当普遍的问题,但我想知道为什么我一直在努力寻找答案。
编辑: 从这个博客条目来看,它看起来不像是直接可能的:NHibernate & Null Object Pattern: The Options
我想在我的域中使用 Null 对象模式,但我不想在我的数据库中有与之相关的记录 - 如果 NHibernate 能够将 SQL 空值映射到我的 Null 对象,我会更喜欢它,反之亦然。
这可能吗(使用 Fluent NHibernate 进行映射)
PS 这似乎是人们希望解决的一个相当普遍的问题,但我想知道为什么我一直在努力寻找答案。
编辑: 从这个博客条目来看,它看起来不像是直接可能的:NHibernate & Null Object Pattern: The Options
在不流利的 nhibernate 中,您可以使用不会像这样持久保存到数据库的导入映射;
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="MyProject.MiddleTier"
assembly="MyProject.MiddleTier">
<import class="ThingNotToPersist"/>
</hibernate-mapping>
不知道这如何流畅地工作,但希望它能给你一个入门。
答案是……你不能。Oren 说“NHibernate 的 null 概念不是您可以轻易更改的,而且它不会通过拦截器来做到这一点。您可以将 null 对象用于值类型(使用 UserType),但不能用于实体。”
好的,既然发布了这个问题,NHibernate 3 就发布了——也许现在有可能?
我不愿意放手——我想使用空对象模式,而且我不会满足于“你不能”,所以让我们想办法实现这一点!
我在网络上的几篇文章和笔记中遇到的一个想法是使用两个属性 - 一个具有公共(未映射)访问权限,一个具有私有(映射)访问权限 - 因此公共属性的 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;
}
}
简而言之,在加载时用空对象替换空值;保存前,用实际的空值替换空对象,保存后,用回空对象替换。
当使用查询 API 时,您当然需要查询实际的空值,但如果您在查询 API 上有某种标准构建器或工厂类,则可以在那里进行说明。
将您的类型扩展为专用的空对象类型并使其非持久化。不知何故。
只是一个想法-假设您要将类型扩展为专用的空对象类型。类似于以下内容:
class Bar
{
public static NullBar; // instace of NullBar
}
class NullBar : Bar
{
// ...
}
现在 NullBar 是扩展 Bar 的专用类型,我们能否以某种方式告诉 NHibernate 不要映射 Nullar 类型,即使它扩展了已映射的 Bar?
这些是我的想法——其中任何一个听起来都合理吗?
(顺便说一句,我是一个 NHibernate 菜鸟——但我很坚持,并不是说你可以拯救我并将我留待以后使用。)