Eager正在使用流利的NHibernate / Nhibernate&自动映射 [英] Eager Loading Using Fluent NHibernate/Nhibernate & Automapping

查看:182
本文介绍了Eager正在使用流利的NHibernate / Nhibernate&自动映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有要求加载一个名为 Node 的复杂对象...以及它不那么复杂...它看起来像这样: - $ /

Node EntityType 具有 的一对多的引用,属性 PorpertyListValue 一对多

  public class Node 
{
public virtual int Id
{
get;
set;
}

公共虚拟字符串名称
{
get;
set;
}

public virtual EntityType Etype
{
get;
set;




$ b public class EntityType
{
public virtual int Id
{
得到;
set;
}

公共虚拟字符串名称
{
get;
set;
}

公共虚拟IList<属性>属性
{
get;
保护组;

$ b $ public EntityType()
{
Properties = new List< Property>();



public class Property
{
public virtual int Id
{
get;
set;
}

公共虚拟字符串名称
{
get;
set;
}

public virtual EntityType EntityType
{
get;
set;
}

公共虚拟IList< PropertyListValue> ListValues
{
get;
保护组;
}

公共虚拟字符串DefaultValue
{
get;
set;

$ b $ public Property()
{
ListValues = new List< PropertyListValue>();



$ b public class PropertyListValue
{
public virtual int Id
{
get;
set;
}

公共虚拟物业物业
{
get;
set;
}

公共虚拟字符串值
{
get;
set;

$ b保护PropertyListValue()
{
}
}

我试图做的是一次加载所有子对象的Node对象。没有延迟加载。原因是我有数以千计的数据库中的节点对象,我必须通过使用WCF服务的电线发送它们。我碰到类SQL N + 1的问题。我在自动映射中使用Fluent Nhibernate,NHibernate Profiler建议我使用 FetchMode.Eager 一次加载整个对象。我正在使用以下qyuery

  Session.CreateCriteria(typeof(Node))
.SetFetchMode(Etype, FetchMode.Join)
.SetFetchMode(Etype.Properties,FetchMode.Join)
.SetFetchMode(Etype.Properties.ListValues,FetchMode.Join)

OR使用NHibernate LINQ

  Session.Linq< ; NodeType>()
.Expand(Etype)
.Expand(Etype.Properties)
.Expand(Etype.Properties.ListValues)

当我运行上面的任何查询时,它们都会生成一个与所有左外连接相同的单个查询,这就是我需要。但是,由于某种原因,从查询返回的IList没有被加载属性的对象。事实上,返回的节点计数等于查询的行数,所以节点对象是重复的。而且,每个节点中的属性重复,Listvalues也一样。



所以我想知道如何修改上面的查询来返回所有具有属性和列表值的唯一节点。



感谢
Nabeel

解决方案

我自己搞清楚了。关键是使用 SetResultTransformer()传递 DistinctRootEntityResultTransformer 的一个对象作为参数。因此,现在的查询如下所示:

$ p $ Session $ CreateCriteria(typeof(Node))
.SetFetchMode(Etype ,FetchMode.Join)
.SetFetchMode(Etype.Properties,FetchMode.Join)
.SetFetchMode(Etype.Properties.ListValues,FetchMode.Join)
.SetResultTransformer(new DistinctRootEntityResultTransformer());

我通过这些链接找到了我的问题的答案:

http://www.mailinglistarchive。 com / html / nhusers@googlegroups.com/2010-05/msg00512.html



http://ayende.com/Blog/archive/2010/01/16/eagerly -loading-entity-associations-efficient-with-nhibernate.aspx


I have a requirement to load a complex object called Node...well its not that complex...it looks like follows:-

A Node has a reference to EntityType which has a one to many with Property which in turn has a one to many with PorpertyListValue

public class Node
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual string Name
    {
        get;
        set;
    }

    public virtual EntityType Etype
    {
        get;
        set;
    }

}


public class EntityType
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual string Name
    {
        get;
        set;
    }

    public virtual IList<Property> Properties
    {
        get;
        protected set;
    }

    public EntityType()
    {
        Properties = new List<Property>();
    }
}

public class Property
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual string Name
    {
        get;
        set;
    }        

    public virtual EntityType EntityType
    {
        get;
        set;
    }

    public virtual IList<PropertyListValue> ListValues
    {
        get;
        protected set;
    }

    public virtual string DefaultValue
    {
        get;
        set;
    }

    public Property()
    {
        ListValues = new List<PropertyListValue>();
    }
}


public class PropertyListValue
{
    public virtual int Id
    {
        get;
        set;
    }

    public virtual Property Property
    {
        get;
        set;
    }

    public virtual string Value
    {
        get;
        set;
    }

    protected PropertyListValue()
    {
    }
}

What I a trying to do is load the Node object with all the child objects all at once. No Lazy load. The reason is I have thousands of Node objects in the database and I have to send them over the wire using WCF Service.I ran into the classes SQL N+ 1 problem. I am using Fluent Nhibernate with Automapping and NHibernate Profiler suggested me to use FetchMode.Eager to load the whole objects at once. I am using the following qyuery

     Session.CreateCriteria(typeof (Node))
            .SetFetchMode( "Etype", FetchMode.Join )
            .SetFetchMode( "Etype.Properties", FetchMode.Join )
            .SetFetchMode( "Etype.Properties.ListValues", FetchMode.Join )

OR using NHibernate LINQ

        Session.Linq<NodeType>()
         .Expand( "Etype")
         .Expand( "Etype.Properties" )
         .Expand( "Etype.Properties.ListValues" )

When I run any of the above query, they both generate one same single query with all the left outer joins, which is what I need. However, for some reason the return IList from the query is not being loaded property into the objects. Infact the returned Nodes count is equal to the number of rows of the query, so the Nodes objects are repeated.Moreover, the properties within each Node are repeated, and so do the Listvalues.

So I would like to know how to modify the above query to return all unique Nodes with the properties and list values within them.

Thanks Nabeel

解决方案

I figure it out myself. The key is to use SetResultTransformer() passing an object of DistinctRootEntityResultTransformer as a parameter. So the query now looks like as follows

Session.CreateCriteria(typeof (Node))
   .SetFetchMode( "Etype", FetchMode.Join )
   .SetFetchMode( "Etype.Properties", FetchMode.Join )
   .SetFetchMode( "Etype.Properties.ListValues", FetchMode.Join )
   .SetResultTransformer(new DistinctRootEntityResultTransformer());

I found the answer to my questions through these links:

http://www.mailinglistarchive.com/html/nhusers@googlegroups.com/2010-05/msg00512.html

http://ayende.com/Blog/archive/2010/01/16/eagerly-loading-entity-associations-efficiently-with-nhibernate.aspx

这篇关于Eager正在使用流利的NHibernate / Nhibernate&amp;自动映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆