我正在使用NHibernate 2.1.2.400,我遇到了ISQLQuery查询的问题。
我在这里使用ISQLQuery的原因是这个查询使用了一个表,我没有在NHibernate中映射实体。
查询如下所示:
ISQLQuery query = session.CreateSQLQuery (
"select p.*, price.* " +
"from prestation p left outer join prestationprice price on p.PrestationId = price.PrestationId " +
"where p.Id IN ( select id from prestationregistry where ...");
'Prestationregistry'是NHibernate不知道的表(未映射,因此是本机SQL查询)。
我的代码继续这样:
query.AddEntity ("p", typeof(Prestation));
query.AddJoin ("price", typeof(PrestationPrice));
query.SetResultTransformer (Transformers.DistinctRootEntity);
var result = query.List();
到目前为止一切顺利。 由于我将'Prestation'声明为必须由AddEntity方法返回的根对象,因此我希望我得到一个'Prestation'实例列表作为此查询的结果。 我还期望这个查询急切地加载每个Prestation的PrestationPrices(因此AddJoin方法)。
令我惊讶的是,List()方法返回PrestationPrice实例的集合而不是Prestation实例。 怎么会 ?难道我做错了什么 ?如果是这样,你能不能告诉我我做错了什么?
编辑:其他信息:
当我调试并对'query'实例进行监视时,我可以看到查询的queryReturns
成员包含2个项目:
- 一个NativeSqlQueryRootReturn实例,其中ReturnEntityName为'Prestation'
- 一个NativeSqlQueryJoinReturn
当我没有指定'DistinctRootEntity'结果转换器时,查询返回'Prestation'而不是PrestationPrice的实例。但是,它包含同一实例的多个副本。
答案 0 :(得分:2)
我不确定这是否是您问题的真正原因,但您必须将SQL别名括在大括号中,例如。
select {p.*}, {price.*}
from prestation p
left outer join prestationprice price on p.PrestationId = price.PrestationId
where p.Id IN ( select id from prestationregistry where ...
答案 1 :(得分:0)
尝试在List
方法中指定要返回的类型:
var result = query.List<Prestation>();
答案 2 :(得分:0)
我以稍微不同的方式解决了这个问题。 我不知道你可以使用SQL表达式作为ICriteria标准(对于NH-Users google-group),所以我这样做:
ICriteria crit = session.CreateCriteria (typeof(Prestation), "p");
crit.SetFetchMode ("p.Prices", FetchMode.Eager);
crit.Add (Expression.Sql ("{alias}.PrestationId = ( SELECT id FROM sometable WHERE ... "));
crit.SetResultTransformer (Transformers.DistinctRootEntity);
var result = crit.List<Prestation>();
无论如何,问题仍然存在,如果我使用ISQLQuery获得的行为是预期的,还是一个bug ......