NHibernate标准变换结果

时间:2010-06-11 12:40:27

标签: nhibernate

我有一个具有Memebers和Application属性的SecurityGroup实体。 应用程序是查找。

因此,securityGroups与User表存在多对多关系,与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 个答案:

答案 0 :(得分:3)

您只能返回您创建条件的类型。

从您拥有的代码开始,最简单的方法是:

    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 ,它具有条件中没有的一些功能,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>();

答案 1 :(得分:0)

这取决于SecurityGroup的外观以及LookupApplication的外观。

您可以使用ResultTransformer,如:

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

授予SecurityGroup具有属性matchinig 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>();