Что можно использовать в качестве псевдонима NHibernate QueryOver?
До сих пор я знаю, что локальная переменная или локальное свойство могут быть использованы в качестве псевдонима, как так
ClassA _aliasA;
_session.QueryOver(x => x.ClassA, () => _aliasA);
или же
ClassA AliasA { get; set; }
_session.QueryOver(x => x.ClassA, () => AliasA);
Я хочу знать, какие другие варианты возможны. Например, допустимы ли свойства внешнего класса?
class ClassGenericAliases
{
ClassA Class { get; set; }
}
_session.QueryOver(x => x.ClassA, () => ClassGenericAliases.ClassA);
Можно ли использовать статику как псевдонимы? Есть ли другие варианты объявления псевдонимов?
2 ответа
Я бы порекомендовал никогда не использовать что-либо для псевдонима вне области метода, который использует псевдоним.
QueryOver - строго типизированная версия Criteria, в Criteria псевдонимом является строковое значение.
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateAlias("Kittens", "kt")
.CreateAlias("Mate", "mt")
.Add( Expression.EqProperty("kt.Name", "mt.Name") )
.List();
Но теперь ему нужно присвоить псевдоним переменной, поэтому мы просто создадим его для него:
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");
Из документации NHForge говорится следующее:
http://nhibernate.info/doc/nh/en/index.html
15,5. Псевдонимы
В традиционном интерфейсе ICriteria псевдонимы назначаются с использованием "волшебных строк", однако их значение не соответствует имени в домене объекта. Например, когда псевдоним назначается с помощью.CreateAlias ("Kitten", "kittenAlias"), строка "kittenAlias" не соответствует свойству или классу в домене.
В QueryOver псевдонимы назначаются с помощью пустой переменной. Переменная может быть объявлена где угодно (но должна быть нулевой во время выполнения). Затем компилятор может проверить, правильно ли используется синтаксис для переменной, но во время выполнения переменная не оценивается (она просто используется в качестве заполнителя для псевдонима).
Каждая функция лямбда-выражения в QueryOver имеет соответствующую перегрузку, позволяющую использовать псевдонимы, и функцию.JoinAlias для обхода ассоциаций с использованием псевдонимов без создания вложенного QueryOver.
Поэтому придерживайтесь только использования переменной в области действия метода.
Мне нужно было решить аналогичную проблему, и я принял решение об именовании псевдонимов. Затем, где бы вам ни понадобилось повторно использовать псевдоним, вы можете проверить его с помощью GetCriteriaByAlias () и добавить его, если его там нет. Возможность повторного использования псевдонима очень удобна, если у вас разные проекции. Этот метод по-прежнему проблематичен, если кто-то игнорирует соглашения об именах, но тогда ваши модульные тесты должны его поднять.
Project aProject = null;
if (root.UnderlyingCriteria.GetCriteriaByAlias("aProject") == null)
root.JoinAlias(i => i.Project, () => aProject);