In my current project, I started using NHibernate and basically everything works nicely, up to a point, where I need to send complete object tree for some entity to the consumer of my service = everything eagerly loaded and sent from the server.
And I want my queries to be as fast as possible.
The search criteria is rather simple: the complete newest result object for the specified product and the specified department.
If i call my query like this, I am getting the correct result: (however this produces 3 queries, still, at least I am getting the correct result)
Result res = session.QueryOver<Result>()
.Where(x => x.Product == product)
.Where(x => x.Department == department)
.OrderBy(x => x.Date).Desc
.Take(1).SingleOrDefault();
However, such result is not eagerly loaded with all the child collections. (and yes, it still creates 3 queries).
For I definitelly need all the items of type ResultContent
in Content
populated. ResultContent
has some collections of elements, that have their collections as well. I desperately need all those collections fully populated with all the child elements and child elements of its child elements and so on.
I played with NHibernate queries nearly whole day now and am nearly achieving correct behavior with query like this:
var resultCriteria = DetachedCriteria.For<Result>();
resultCriteria.SetFetchMode("Product", FetchMode.Eager);
resultCriteria.SetFetchMode("Department", FetchMode.Eager);
resultCriteria.SetFetchMode("Content", FetchMode.Join);
resultCriteria.SetFetchMode("Source", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics", FetchMode.Eager);
resultCriteria.SetFetchMode("Content.Numerics.DataCollection", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription.DescriptionSource", FetchMode.Eager);
resultCriteria.SetMaxResults(5);
var relevantResults = resultCriteria.GetExecutableCriteria(session).List<Result>();
With this approach, I am getting 5 Results, but the Content collection is not populated further than the first element. And for the DataCollection in Numerics, there only are 5 elements queried, even though it should be somewhere near 500 items pulled.
I Played with the FetchModes quite a lot and am starting to think that I will not achieve what I need nowhere near in the future. Could you please hint me in the proper direction how I could combine those 2 approaches properly?
Should I use HQL (I never did, so I think I would struggle even more)?
Note: I googled quite a lot and tried a lot of things, but as far as NHibernate and sql goes, I consider myself quite a noob. I will try improving my skills, but the time pressure now tends towards asking a question.
The other relevant classes look like this (so that you can see which class holds a collection of what, lots of simplifications applied of course)
public class Result
{
public virtual long Id { get; protected set; }
public virtual Product Product { get; set; }
public virtual Department Department { get; set; }
public virtual DateTime Date { get; set; }
public virtual ISet<ResultContent> Content { // getters and setters }
public virtual ISet<ResultSource> Source { // getters and setters }
}
public class Product
{
public virtual short Id { get; protected set; }
public virtual string Name { get; set; }
public virtual string Code { get; set; }
public virtual string Description { get; set; }
}
public class Department
{
public virtual short Id { get; protected set; }
public virtual string Name { get; set; }
public virtual string Code { get; set; }
public virtual string Description { get; set; }
}
public class ResultContent
{
public virtual Result Result { get; set; }
public virtual Numerics Numerics { get; set; }
public virtual long Revision { get; set; }
}
public class Numerics
{
public virtual long Id { get; protected set; }
public virtual string Name { get; set; }
public virtual ISet<DataEntry> DataCollection { //getters and setters }
public virtual ISet<DataDescription> DataDescription { //getters and setters}
}
DataEntry and DataDescription Classes are just holding Id, Date and either string or boolean value.
hi can you try it ,
Result ra = null;
Product pa = null;
Department da = null;
Result res = session.QueryOver<Result>(() => ra)
.JoinAlias(() => ra.Product ,() => pa)
.JoinAlias(() => ra.Department ,() => da)
.Where(() => pa == product)
.Where(() => da == department)
.OrderBy(() => ra.Date).Desc
.Take(1).SingleOrDefault();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.