Paul
Paul

Reputation: 5576

nHibernate - eager fetching a list with child lists already populated

I have some objects:

Public Class Person() {
    public int Id {get;set;}
    public IList<Account> Accounts {get;set;}
    public string Email {get; set;}
}

public class Account(){
    public int Id {get;set;}
    public IList<AccountPayment> Payments {get;set;}
    public IList<Venue> Venues {get;set;}
}

public class AccountPayment(){
    public int Id {get;set;}
    public DateTime PaymentDate {get;set;}
    public decimal PaymentAmount {get;set;}
}

public class Venue(){
    public int Id {get;set;}
    public string AddressLine1 {get;set;}
    public string Postcode {get;set;}
}

These classes are mapped to MS Sql with nHibernate - there is a table in the db per class...

I want to create a method in my repository, GetAccounts(int PersonID), that will return a List with all the account's child collections populated in the most efficient way. Can anyone give me any pointers on how to do this - I do not really want to set up the lists as subselects in my mappings if I can help it...

Thanks.

Upvotes: 4

Views: 2010

Answers (2)

Paul
Paul

Reputation: 5576

Ok, after trying to do this in many different ways, I eventually found that the most efficient solution for me outlined at this question:

Eager loading child collection with NHibernate

My question above was a vastly simplified version of the actual challenge I had, but using the above method managed to get the db hits down to 2... a huge improvement from my initial implementation.

Thanks for your help and pointers guys. Learned a bit along the way...

Upvotes: 0

LordHits
LordHits

Reputation: 5083

If you have mapped your classes to tables the way you mention, why don't you just call the Person object to get all their accounts? When you call the Person object from your repository, you can eager load Accounts. Like so:

 public Person GetById(int id)
    {
        using (var tx = _sessionBuilder.GetSession().BeginTransaction())
        {
            // -- Lazy load way --
            //Person person = _sessionBuilder.GetSession().Get<Person>(id);
            //tx.Commit();
            //return person;

            // -- Eager load way --                
            Person person = _sessionBuilder.GetSession().CreateCriteria<Person>()
                   .Add(Restrictions.IdEq(id))
                   .SetFetchMode("Accounts", FetchMode.Eager)
                   .UniqueResult<Person>();
            tx.Commit();
            return person;
        }
    }

Upvotes: 1

Related Questions