1

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?

Jonn
  • 4,599
  • 9
  • 48
  • 68

2 Answers2

7

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.

Owen Pauling
  • 11,349
  • 20
  • 53
  • 64
Phill
  • 18,398
  • 7
  • 62
  • 102
  • I'm trying to look for ways to reuse those aliases. So, that's not good practice? Having to rewrite those joins again and again are such a pain. – Jonn Aug 01 '11 at 05:26
  • You shouldn't have too many complex joins, otherwise I think you should double take on what you're trying to solve. You can write fetching strategies to reuse Eager fetches on queries. There's nothing to say you can't go and make those queries re-usable. You can return the IQueryOver from a method and add more criteria to it. But generally I think it's best to not try make the alias' re-usable. – Phill Aug 01 '11 at 05:44
2

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);
masdude
  • 43
  • 1
  • 6
  • I ended up with a similar solution. After almost a year of using it in practice, I'd have to say that you'll end up fighting against the design a number of times. It's true though, discipline in writing unit tests will help you a lot here. And what we have is still easier than not being able to reuse them at all. I just know now that were I to do it again, I'd look for one that won't force me to fight against Nhib's framework – Jonn May 11 '12 at 06:34