Критерий преобразования NHibernate Результат - PullRequest
2 голосов
/ 11 июня 2010

У меня есть сущность SecurityGroup, у которой есть свойства Memebers и Application.Приложение является поиском.

Таким образом, securityGroups находится в отношениях «многие ко многим» с таблицей «Пользователь» и «один ко многим» с LookupApplciation (FK)

Теперь я хочу выбрать все приложения, связанные сконкретный пользователь.

У меня есть следующие критерии:

 public IList<LookupApplication> GetApplicationByUser(User user)
    {
        return
            this.Session.CreateCriteria(typeof(SecurityGroup), "sg")
            .CreateAlias("Members", "u")
            .CreateAlias("Application", "al")
            .Add(Restrictions.Eq("u.Id", user.Id))

            .List<LookupApplication>();

    }

Выдает исключение

The value "Edi.Advance.Core.Model.Security.SecurityGroup" is not of type "Edi.Advance.Core.Model.Lookups.LookupApplication" and cannot be used in this generic collection.
Parameter name: value

и это правильно.

Как можноЯ преобразовываю результат в IList<LookupApplication>?

Спасибо

Ответы [ 2 ]

3 голосов
/ 11 июня 2010

Вы можете вернуть только тип, для которого вы создаете критерии.

Самый простой способ, начиная с кода, который у вас есть, будет:

    return
        this.Session.CreateCriteria(typeof(SecurityGroup), "sg")
        .CreateAlias("Members", "u")
        .CreateAlias("Application", "al")
        .Add(Restrictions.Eq("u.Id", user.Id))
        .List<SecurityGroup>()

        // get the lookup applications in memory
        .SelectMany(x => x.LookupApplications);

Это загрузит все SecurityGroups впамяти, даже если для этого нужны только LookupApplication с.Это может не быть проблемой, когда они вам все равно нужны или когда они маленькие.

Вы также можете отменить запрос и начать с LookupApplication

    return
        this.Session.CreateCriteria(typeof(LookupApplication), "la")
        // requires navigation path from SecurityGroup to LookupApplication
        .CreateCriteria("la.SecurityGroup", "sg")
        .CreateAlias("Members", "u")
        .CreateAlias("Application", "al")
        .Add(Restrictions.Eq("u.Id", user.Id))
        .List<LookupApplication>()

Или использовать HQL , который имеет некоторые функции, недоступные в Criteria, items получает все элементы из коллекции:

select sg.LookupApplications.items
from SecurityGroup sg inner join sg.Members u
where u.Id = :userId

HQL действительно рекомендуется, когда у вас нет динамических запросов.

Обновление , из комментария isuruceanu:

Session
  .CreateQuery(
      @"select sg.Application 
      from SecurityGroup sg 
          inner join sg.Members u 
      where u.Id = :userId") 
  .SetParameter("userId", user.Id)
  .List<LookupApplication>();
0 голосов
/ 11 июня 2010

Это зависит от того, как выглядит SecurityGroup и как выглядит LookupApplication.

Вы можете использовать ResultTransformer как:

.SetResultTransformer(Transformers.AliasToBean<LookupApplication>())
.List<LookupApplication>();

Предполагается, что SecurityGroup имеет свойства, совпадающие с LookupAppliaction, иначе вы должны проецировать такие свойства как:

.SetProjection(NHibernate.Criterion.Projections.ProjectionList()    
.Add(Projections.Property("Number"), "OrderNumber")
.Add(Projections.Property("CreatedOn"), "CreatedOn")
   .Add(Projections.Property("MemeberName"), "Name"))
 .SetResultTransformer(Transformers.AliasToBean<LookupApplication>())
 .List<LookupApplication>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...