在使用ReferencesAny时,如何配置Fluent NHibernate以返回null而不是缺少对象的代理

Mat*_*t B 2 .net c# nhibernate fluent-nhibernate fluent-nhibernate-mapping

根据标题,我有一个具有ReferencesAny关联的对象,但引用的对象可能已被删除.如果发生这种情况,则当前使用代理初始化缺少的对象,如果访问则抛出ObjectNotFound.我希望能够以类似的方式将此返回null设置为在其他属性上设置not-found为"ignore".我理解使用Session.Get和Session.Load之间的区别,但这是LINQ查询的结果.

所以,我的问题是,如何指定为"任何"关联丢失的对象应返回null?

Rad*_*ler 5

我正在使用xml配置,但我想我的提示无论如何都可以帮助你...... NHibernate为那些不完整的映射提供了一个未找到的属性,默认设置为" exception ".在这个例子中是引用多对一映射,但它甚至可以用于一对多

<many-to-one name="MyReferencedObject" not-found="exception" />
Run Code Online (Sandbox Code Playgroud)

但它可以改为忽略

<many-to-one name="MyReferencedObject" not-found="ignore" />
Run Code Online (Sandbox Code Playgroud)

在这种情况下,结果将为NULL.(但要小心,NHibernate将始终执行SQL select语句,因为这样的"NULL"值不会被缓存)


编辑:根据下面的评论,我不得不说,我的建议不适用于<any>映射.对不起,我应该仔细阅读......但是,请允许我为您提供建议,如何解决.


我们可以介绍事件监听器.更多内容可以在这里找到http://nhibernate.info/doc/nh/en/index.html#objectstate-events

解决方案简而言之:

介绍事件监听器

public class PostLoadListener 
           : NHibernate.Event.Default.DefaultPostLoadEventListener
{ ... }
Run Code Online (Sandbox Code Playgroud)

并将其注入"会话工厂"配置.

<event type="post-load">
    <listener class="MyLib.PostLoadListener, MyLib"/>
</event>
Run Code Online (Sandbox Code Playgroud)

诀窍在于覆盖方法OnPostLoad

public override void OnPostLoad(PostLoadEvent @event)
{
    base.OnPostLoad(@event);

    // the entity with <any> mapping 
    ConvertToNull(@event.Entity as MyAuditEntity); 
}

protected virtual void ConvertToNull(MyAuditEntity item)
{
    if (item == null)
    {
        return;
    }
    try
    {
        // access some property to check that reference is not a PROXY
        var id = item.AnyEntity.ID;
    }
    catch
    {
        // replace proxy with null
        item.AnyEntity = null; 
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这不是像not-found ="ignore"的答案.但这种解决方法将完成这项工作.