问题
I would like to override the default lazy loading behavior which is set in mappings as 'lazy=false'. Can't change it as many parts of existing application depend on this setting.
After spent some hours on it I didn't find a solution so I'm asking here.
How to do this?
What I want to achieve is to fine tune my query to load only what is needed.
This is what I've tried already:
Using QueryOver
api:
var properties = session.QueryOver<Property>()
.Fetch(prop => prop.Transactions).Eager
.Fetch(prop => prop.Districts).Eager
//I dont want to load those entities below so I mark
//them as lazy - IT DOESN'T WORK
//I can see in SQL that they are getting loaded in separate queries
.Fetch(prop => prop.Districts.First().Aliases).Lazy
.Fetch(prop => prop.Districts.First().PolygonPoints).Lazy
.Skip(i * pageSize)
.Take(pageSize)
.List();
Using Criteria
api:
var criteria = session.CreateCriteria<Property>();
criteria.SetFetchMode("Transactions", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts", NHibernate.FetchMode.Join);
criteria.SetFetchMode("Districts.Aliases", NHibernate.FetchMode.Select); // tried Lazy too
criteria.SetFetchMode("Districts.PolygonPoints", NHibernate.FetchMode.Select); // tried Lazy too
criteria.AddOrder(NHibernate.Criterion.Order.Asc("Id"));
criteria.SetFirstResult(i * pageSize);
criteria.SetMaxResults(pageSize);
var properties = criteria.List<Property>();
Using any of the above methods 'Aliases' and 'PolygonPoints' are always being loaded when calling List<>()
. I don't need them in my process.
I'm using Nhibernate 4.0.
Any ideas?
回答1:
We cannot override mapping in this case. We can do it opposite way - have lazy in place - and use eager fetching for querying.
The decision process (of reference loading)
is done outside of the query, ex post. So it could be pre-loaded, but cannot be avoided.
Solution here could be of two types.
- The first is preferred (by me) - do your best and make laziness the default: Ayende - NHibernate is lazy, just live with it
- Use
projections
. Instruct NHibernate to create just one query, use transformer to get expected object graph - without any proxies in it
There is pretty clear example how to (properly) use projection list even for references:
- Fluent NHibernate - ProjectionList - ICriteria is returning null values
And we would also need Custom result transformer, which will ex-post create all the references from the returned data:
- Custom DeepResultTransfomer
来源:https://stackoverflow.com/questions/30166946/override-lazy-loading-behavior-lazy-false