-
Notifications
You must be signed in to change notification settings - Fork 3
Specify load strategy per query #82
Description
Eager loading of relationships is a performance improvement where the relationship is accessed in the same session. However, not all queries on the same resource will require the same relationship access, which means those queries actually take a performance hit instead. The Load Strategy is defined on the model itself, which means the implementer has to guess at how the relationships will be used in general and choose the better of two evils.
It would be better to override the Load Strategy per query, so that the implementer can tune performance on a query-by-query basis. If the implementer knows the relationship data will be used, it can be eagerly loaded for that query. If the Load Strategy on the model is eager and that relationship data will not be used, then the implementer could turn off eager loading in that instance. This is consistent with other ORMs and feasible using JsonApi.
Below is one possible look. Otherwise CreateQuery could have additional parameters, or the implementation could be "opt-in only" where the only option is to specify which relationships will be loaded.
// Method PeopleToVisit
var puppies = session
.CreateQuery<Puppy>()
.LoadStrategy(x => x.Owners, LoadStrategy.Eager)
.LoadStrategy(x => x.Leash, LoadStrategy.Lazy)
.Where(x => x.Breed = BreedType.GoldenRetriever);
return puppies
.Select(x => new VisitResponse {
Puppy = x,
OwnerNames = x.Owners.Select(x => x.Name).ToArray();
});
// Method PuppiesToWalk
var puppies = session
.CreateQuery<Puppy>()
.LoadStrategy(x => x.Leash, LoadStrategy.Eager)
.LoadStrategy(x => x.Owners, LoadStrategy.Lazy)
.Where(x => x.LastWalkTime <= DateTime.Now.AddHours(-1));
return puppies
.Select(x => new WalkResponse {
PuppyName = x.Name,
Leash = x.Leash
});
// Opt-in possible look
var puppies = session
.CreateQuery<Puppy>()
.EagerLoad(x => x.Owners)
.EagerLoad("leash");
// CreateQuery possible look
var puppies = session
.CreateQuery<Puppy>(eagerLoad: new [] { "owners" });