NHibernate lazy loading doesn't appear to be working for my domain?
I'm new to NHibernate, but have managed to get it all running fine for my latest project. But now I've reached the inevitable performance problem where I need to get beyond the abstraction to fix it.
I've created a nunit test to isolate the method that takes a long time. But first a quick overview of my domain model is probably a good idea:
I have a 'PmqccForm' which is开发者_如何学Go an object that has a 'Project' object, which contains Name, Number etc and it also has a 'Questions' object, which is a class that itself contains properties for various different 'Question' objects. There is a JobVelocityQuestion object which itself has an answer and some other properties, and a whole bunch of similar Question objects. This is what I'm talking about with my PmqccForm having a Questions object
This is the questions part of the model:
The key point is that I want to be able to type form.Questions.JobVelocityQuestion
as there is always exactly 1 JobVelocityQuestion for each PmqccForm, its the same for all the other questions. These are C# properties on the Questions object which is just a holding place for them.
Now, the method that is causing me issues is this:
public IEnumerable<PmqccForm> GetPmqccFormsByUser(StaffMember staffMember)
{
ISession session = NHibernateSessionManager.Instance.GetSession();
ICriteria criteria = session.CreateCriteria(typeof(PmqccForm));
criteria.CreateAlias("Project", "Project");
criteria.Add(Expression.Eq("Project.ProjectLeader", staffMember));
criteria.Add(Expression.Eq("Project.IsArchived", false));
return criteria.List<PmqccForm>();
}
A look in my console from the Nunit test which just runs this method shows that there is nearly 2000 sql queries being processsed! http://rodhowarth.com/otherstorage/queries.txt is the console log.
The thing is, at this stage I just want the form object, the actual questions can be accessed on a need to know basis. I thought that NHibernate was meant to be able to do this?
Here is my mapping file: http://rodhowarth.com/otherstorage/hibernatemapping.txt
Can anyone hint me as to what I'm missing? or a way to optimize what I'm doing in relation to NHibernate?
What if I made the questions a collection, and then made the properties loop through this collection and return the correct one. Would this be better optimization from nhibernates point of view?
Just try to add fetch="subselect" to the mapping file for Questions component and see if this solves the issue with multiple selects to that table - you should now see one 2nd select instead of hundreds separate queries, e.g.
<component name="Questions" insert="true" update="true" class="PmqccDomain.DomainObjects.Questions" fetch="subselect">
See for more info - Improving performance
精彩评论