Hello,
I have quite complex database model, an Ad has a collection of Details, every Detail has reference to Parameter, a Parameter belongs to a Group and to a Field.
A Field has OptionItems and Units.
OptionItem, Unit and a Group have Translations collection.
There are more relations, but these mentioned above are the most relevant.
I need to get efficiently full object graph for specific Ad. My solution gets it in one query, but there are too many joins and I get a cartesian product.
My query:
Code:
var ad = _session.CreateCriteria<Ad>("ad")
//Address with Country and Country Translations
.CreateAlias("Address", "address", JoinType.LeftOuterJoin)
.SetFetchMode("address", FetchMode.Eager)
.CreateAlias("address.Country", "country", JoinType.LeftOuterJoin)
.SetFetchMode("country", FetchMode.Eager)
.CreateAlias("country.Translations", "countryTranslations", JoinType.LeftOuterJoin)
.SetFetchMode("countryTranslations", FetchMode.Eager)
//Details
.CreateAlias("Details", "details", JoinType.LeftOuterJoin)
.SetFetchMode("details", FetchMode.Eager)
//Parameter
.CreateAlias("details.Parameter", "parameter", JoinType.LeftOuterJoin)
.SetFetchMode("parameter", FetchMode.Eager)
//Group with Translations
.CreateAlias("parameter.Group", "group", JoinType.LeftOuterJoin)
.SetFetchMode("group", FetchMode.Eager)
.CreateAlias("group.Translations", "groupTranslations", JoinType.LeftOuterJoin)
.SetFetchMode("groupTranslations", FetchMode.Eager)
//Field
.CreateAlias("parameter.Field", "field", JoinType.LeftOuterJoin)
.SetFetchMode("field", FetchMode.Eager)
.CreateAlias("field.Translations", "fieldTranslations", JoinType.LeftOuterJoin)
.SetFetchMode("fieldTranslations", FetchMode.Eager)
//OptionItems with translations
.CreateAlias("field.OptionItems", "optionItems", JoinType.LeftOuterJoin)
.SetFetchMode("optionItems", FetchMode.Eager)
.CreateAlias("optionItems.Translations", "optionItemTranslations", JoinType.LeftOuterJoin)
.SetFetchMode("optionItemTranslations", FetchMode.Eager)
//Units with translations
.CreateAlias("field.Units", "unit", JoinType.LeftOuterJoin)
.SetFetchMode("unit", FetchMode.Eager)
.CreateAlias("unit.Translations", "unitTranslations", JoinType.LeftOuterJoin)
.SetFetchMode("unitTranslations", FetchMode.Eager)
.CreateAlias("Images", "images", JoinType.LeftOuterJoin)
.SetFetchMode("images", FetchMode.Eager)
.CreateAlias("Make", "make", JoinType.LeftOuterJoin)
.SetFetchMode("make", FetchMode.Eager)
.CreateAlias("make.Models", "model", JoinType.LeftOuterJoin)
.SetFetchMode("model", FetchMode.Eager)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.Add(Restrictions.Eq("Id", id))
.UniqueResult<Ad>();
As you can see it gets huge... And not really efficient.
Any ideas how to optimize it using NHibernate?
Thanks in advance.
Marek