What can be used as a NHibernate QueryOver alias?

Jonn picture Jonn · Aug 1, 2011 · Viewed 12.3k times · Source

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?

Answer

Phill picture Phill · Aug 1, 2011

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.