NHibernate的标准与不同的父加载所有的孩子? [英] NHibernate Criteria with Distinct Parent Load All Children?

查看:105
本文介绍了NHibernate的标准与不同的父加载所有的孩子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父母子女关系,我想只返回一个父母并加载所有子女。

  var messageQueueId = this.GetPropertyName< MessageQueue>(x => x 。ID); 

var query = _sessionManager.Session.CreateCriteria< MessageQueue>(QUEUE_ALIAS);

query.SetFirstResult(_pageOffset);
query.SetMaxResults(_pageSize);
query.Add(Restrictions.In(messageQueueId,_messageQueueIds));

query.List< MessageQueue>();

这将返回父级(MessageQueue),但不是子级(SearchMatches)。
$ b

当我尝试这样做时:

$ $ $ $ $ $ c $ var变量查询_sessionManager.Session
.CreateCriteria< MessageQueue>(QUEUE_ALIAS)
.CreateAlias(this.GetPropertyName< MessageQueue>(x => x.SearchMatches)
,MATCH_ALIAS,JoinType.LeftOuterJoin);

然后我得到孩子加载,但我也收到重复的父母。我明白为什么会发生这种情况。然而,我不明白如何得到第一个场景自动加载SearchMatches?



这是我的实体:

  public class MessageQueue:EntityBase 
{
...
公共虚拟IList< SearchMatch> SearchMatches {get;组; }
...
}

public class SearchMatch:EntityBase
{
...
public virtual MessageQueue MessageQueue {get;组; }
...
}

流利的NHibernate被设置为 DefaultCascade.All()。我已经尝试使用 Inverse()关闭MessageQueue覆盖Not.LazyLoad()。也尝试EagerLoad关闭CreateAlias。但我仍然没有得到我所需要的东西。

解决方案

我会建议使用 batch-size = 设置。它将最终在
1)由我们发出一个查询( query.List< MessageQueue>(); ),

)NHibernate将使用一个(或少数)查询来为每个返回的 MessageQueue 加载集合。



< h3> 19.1.5。使用批量抓取


NHibernate可以高效地使用批量抓取,也就是说,NHibernate可以加载一些未初始化的代理,如果一个代理(或集合)批量读取是对懒惰选择读取策略的优化有两种方式可以调整批量读取:在类和集合级别上。

对于类/实体的批量获取比较容易理解,假设你在运行时有以下情况:在一个ISession中加载了25个Cat实例,每个Cat都有一个对它的Owner,Person的引用,Person类映射为proxy,lazy =true。如果你现在迭代所有的猫,并调用cat.Owner,NHibernate将默认执行25条SELECT语句来检索代理的所有者,你可以通过指定一个批处理大小Person的映射:



 < class name =Personbatch-size = 10\" > ...< /类> 

流利的选择是(集合和类级别)

  .BatchSize(25)

同时检查:


  • 如何在使用Oracle的时候用Fluent NHibernate实现批量抓取?

  • 如何在NHibernate中没有重复的负载关联?
  • 使用NHibernate QueryOver获取结果多个sql查询和db命中



    注意:最后,作为批量大小,例如25,似乎被用作它的一半 - 12.所以,如果你做了25的大小的分页,试着用 SetBatchSize(50)



    I have a parent child relationship where I want to return only one parent and load all the children. I am using criteria because it is a dynamic query.

    var messageQueueId = this.GetPropertyName<MessageQueue>(x => x.Id);
    
    var query = _sessionManager.Session.CreateCriteria<MessageQueue>(QUEUE_ALIAS);
    
    query.SetFirstResult(_pageOffset);
    query.SetMaxResults(_pageSize);
    query.Add(Restrictions.In(messageQueueId, _messageQueueIds));
    
    query.List<MessageQueue>();
    

    This returns the parent (MessageQueue) but not it's children (SearchMatches).

    When I try to do this:

    var query = _sessionManager.Session
        .CreateCriteria<MessageQueue>(QUEUE_ALIAS)
        .CreateAlias(this.GetPropertyName<MessageQueue>(x => x.SearchMatches)
                    , MATCH_ALIAS, JoinType.LeftOuterJoin);
    

    Then I get the children loaded, but also I receive duplicate parents. I understand why this is happening. However I don't understand how to get the first scenario to just load the SearchMatches automatically?

    Here are my entitites:

    public class MessageQueue : EntityBase
    {
        ...
        public virtual IList<SearchMatch> SearchMatches { get; set; }
        ...
    }
    
    public class SearchMatch : EntityBase
    {
        ...
        public virtual MessageQueue MessageQueue { get; set; }
        ...
    }
    

    Fluent NHibernate is set to DefaultCascade.All(). I have no other overrides for these objects.

    I have tried to use Inverse() and Not.LazyLoad() off of the MessageQueue override. Also Tried to EagerLoad off the CreateAlias. But I am still not getting what I need back.

    解决方案

    I would suggest to use the batch-size="" setting. It will end up in
    1) one query issued by us (query.List<MessageQueue>();),
    2) NHibernate will use then one (or just few) query/ies to load collection for each returned MessageQueue.

    19.1.5. Using batch fetching

    NHibernate can make efficient use of batch fetching, that is, NHibernate can load several uninitialized proxies if one proxy is accessed (or collections. Batch fetching is an optimization of the lazy select fetching strategy. There are two ways you can tune batch fetching: on the class and the collection level.

    Batch fetching for classes/entities is easier to understand. Imagine you have the following situation at runtime: You have 25 Cat instances loaded in an ISession, each Cat has a reference to its Owner, a Person. The Person class is mapped with a proxy, lazy="true". If you now iterate through all cats and call cat.Owner on each, NHibernate will by default execute 25 SELECT statements, to retrieve the proxied owners. You can tune this behavior by specifying a batch-size in the mapping of Person:

    <class name="Person" batch-size="10">...</class>
    

    The fluent alternative is (both collection and class level)

    .BatchSize(25)
    

    Also check:

    NOTE: At the end, the number passed as a batch size, e.g. 25, seems to be used as its half - 12. So if you do paging on a size of 25, try to use SetBatchSize(50)

    这篇关于NHibernate的标准与不同的父加载所有的孩子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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