NHibernate Eager Fetching Over Multiple Levels

后端 未结 5 1796
野的像风
野的像风 2020-12-12 22:53

I have a 3-leveled hierarchy of entities: Customer-Order-Line, which I would like to retrieve in entirety for a given customer, using ISession.Get(id). I have the following

相关标签:
5条回答
  • 2020-12-12 23:27

    If you need to keep your one-to-manys as bags, then you can issue 2 queries, each with only 1 level of hierarchy. eg something like this:

    var temp = session.CreateCriteria( typeof( Order ) )
        .SetFetchMode( "Lines", NHibernate.FetchMode.Eager )
        .Add( Expression.Eq( "Customer.ID", id ) )
        .List();
    
    var customer = session.CreateCriteria( typeof( Customer ) )
        .SetFetchMode( "Orders", NHibernate.FetchMode.Eager )
        .Add( Expression.Eq( "ID", id ) )
        .UniqueResult();
    

    Lines get loaded into the NH cache in the first query, so they won't need lazy loading when later accessing eg customer.Orders[0].Lines[0].

    0 讨论(0)
  • 2020-12-12 23:38

    @Tigraine: your query only returns Post with Comments. This brings All posts with all Comments (2 levels). What Ben asking is Customer to Order To LineItem (3 level). @Ben: to my knowledge nHibernate doesn't support eager loading upto 3 level yet. Hibernate does support it thou.

    0 讨论(0)
  • 2020-12-12 23:40

    You're getting 4XOrder and 4XLines because the join with lines doubles the results . You can set a Transformer on the ICriteria like :

    .SetResultTransformer(new DistinctRootEntityResultTransformer())
    
    0 讨论(0)
  • 2020-12-12 23:43

    I was having the same problem. See this thread. I didn't get a solution but a hint from Fabio. Use Set instead of bag. And it worked.

    So my suggestion is try to use set. You don't have to use Iesi collection use IDictonary and NH is happy

    public override IEnumerable<Baseline> GetAll()
    {
         var baselines = Session.CreateQuery(@" from Baseline b
                                                left join fetch b.BaselineMilestones bm
                                                left join fetch bm.BaselineMilestonePrevious ")
                                                .SetResultTransformer(Transformers.DistinctRootEntity)
                                                .List<Baseline>();
         return baselines;
    }
    
    0 讨论(0)
  • 2020-12-12 23:44

    I just read Ayende's Blogpost where he used the following Example:

    session.CreateCriteria(typeof(Post))
        .SetFetchMode("Comments", FetchMode.Eager)
        .List();
    

    In a Criteria Query to avoid Lazy Loading on one particular Query

    Maybe that can help you.

    0 讨论(0)
提交回复
热议问题