4
votes

I'm building an Orchard CMS module, where I want to eager load data, but can't work out how to do this.

For example a Client has many Events, so I have a ClientRecord & EventRecord for these:

public class ClientRecord {

    private IList<EventRecord> _eventRecords;

    public virtual int Id { get; set; }

    public virtual string Company { get; set; }

    public virtual IList<EventRecord> EventRecords {
        get { return _eventRecords ?? (_eventRecords = new List<EventRecord>()); }
        set { _eventRecords = value; }
    } 
}

WhenI load a Client in my ClientController

var clientRecord = _clientRepository.Get(id);

and then display the Events in my View

    <ul>
        @foreach (var eventRecord in Model.EventRecords) {
            <li>
                @eventRecord.Name (@eventRecord.StartDate.ToShortDateString())
            </li>
        }
    </ul>

the Events are displayed and MiniProfiler shows a separate query to lazy-load the Events.

I've tried putting an [Aggregate] attribute on the EventRecords collection in the ClientRecord, but this didn't have any effect.

I'm not that familiar with NHibernate, so hopefully this is something simple, but how do I specify I want to eager load the EventRecords when the ClientRecord is retrieved?

[EDIT]

In Orchard CMS the NHibernate mappings are created for you, based on the convention that the class is called xxxRecord and there is a database table in place with the same name.

So you don't (as far as I know) have a mapping file that you can specify this in. If I'm right about that, then the question is whether there is any way to specify you want eager loading in the query you use to retrieve the Client (rather like Entity Framework's "include" method).

1
Can you show your class mapping?Andrew Whitaker
@Andy There isn't a mapping file in Orchard CMS. I've edited my question to explain how I understand that it works.Appetere

1 Answers

1
votes

You must specify eager loading in your nHibernate mapping file, using Fluent nhibernate this would look (something) like this:

HasMany(x => x.EventRecords).KeyColumn("CompanyId").Not.LazyLoad().Fetch.Select();

The Fetch.Select() will execute a second select statement to load all of the related Event records.

The Not.LazyLoad() tells nHibernate to execute this second select immediately, if you remove this execution would be deferred until the collection is accessed.

In response to your comments you can specify eager loading in your query using fetch also (LINQ example shown)

NHSession.Query<ClientRecord>().Fetch(c => c.EventRecords).ToList();