I know so far that a local variable or a local property can be used as an alias like so
ClassA _aliasA;
_session.QueryOver(x => x.ClassA, () => _aliasA);
or
ClassA AliasA { get; set; }
_session.QueryOver(x => x.ClassA, () => AliasA);
I want to know what other options are possible. Like, are properties of an external class a valid option?
class ClassGenericAliases
{
ClassA Class { get; set; }
}
_session.QueryOver(x => x.ClassA, () => ClassGenericAliases.ClassA);
Can statics be used as aliases?
Are there other options for declaring aliases?
I would recommend never using anything for an Alias outside of the scope of the method that uses the alias.
QueryOver is a strongly typed version of Criteria, in Criteria an alias was a string value.
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateAlias("Kittens", "kt")
.CreateAlias("Mate", "mt")
.Add( Expression.EqProperty("kt.Name", "mt.Name") )
.List();
But now it needs to assign the alias to a variable so we just create one for it:
Cat catAlias = null;
Kitten kittenAlias = null;
IQueryOver<Cat,Cat> catQuery =
session.QueryOver<Cat>(() => catAlias)
.JoinAlias(() => catAlias.Kittens, () => kittenAlias)
.Where(() => catAlias.Age > 5)
.And(() => kittenAlias.Name == "Tiddles");
From NHForge documentation, it says the following:
http://nhibernate.info/doc/nh/en/index.html#queryqueryover-aliases
15.5. Aliases
In the traditional ICriteria interface aliases are assigned using
'magic strings', however their value does not correspond to a name in
the object domain. For example, when an alias is assigned using
.CreateAlias("Kitten", "kittenAlias"), the string "kittenAlias" does
not correspond to a property or class in the domain.
In QueryOver, aliases are assigned using an empty variable. The
variable can be declared anywhere (but should be null at runtime). The
compiler can then check the syntax against the variable is used
correctly, but at runtime the variable is not evaluated (it's just
used as a placeholder for the alias).
Each Lambda Expression function in QueryOver has a corresponding
overload to allow use of aliases, and a .JoinAlias function to
traverse associations using aliases without creating a sub-QueryOver.
So stick to just using a variable in the scope of the method.
I needed to solve a similar issue and decided on an alias naming convention. Then where ever you needed to reuse the alias you can check for it using GetCriteriaByAlias() and add it if it is not there.
Being able to reuse the alias is very handy if you have different select projections. This method is still problematic if someone disregards naming conventions, but then your unit tests should pick that up.
Project aProject = null;
if (root.UnderlyingCriteria.GetCriteriaByAlias("aProject") == null)
root.JoinAlias(i => i.Project, () => aProject);