我有一个具有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>?
由于
答案 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>();