Linq to NHibernate 多个 OrderBy 调用

Posted

技术标签:

【中文标题】Linq to NHibernate 多个 OrderBy 调用【英文标题】:Linq to NHibernate multiple OrderBy calls 【发布时间】:2010-09-08 19:34:58 【问题描述】:

我在 Linq to NHibernate 查询中按多个字段排序时遇到问题。有谁知道可能出了什么问题或者是否有解决方法?

代码:

IQueryable<AgendaItem> items = _agendaRepository.GetAgendaItems(location)
   .Where(item => item.Minutes.Contains(query) || item.Description.Contains(query));

int total = items.Count();

var results = items
   .OrderBy(item => item.Agenda.Date)
   .ThenBy(item => item.OutcomeType)
   .ThenBy(item => item.OutcomeNumber)
   .Skip((page - 1)*pageSize)
   .Take(pageSize)
   .ToArray();

return new SearchResult(query, total, results);

我尝试用多个 OrderBy 调用替换 ThenBy。结果相同。如果我注释掉两个 ThenBy 调用,该方法效果很好。

我收到的错误:

[SqlException(0x80131904):无效的列名'__hibernate_sort_expr_0____hibernate_sort_expr_1__'。 列名 '__hibernate_sort_expr_0____hibernate_sort_expr_1__' 无效。] System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔 breakConnection)+1948826 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection)+4844747 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2392 [ADOException:无法执行查询 [ 选择 this_.Id 作为 Id5_2_,this_.AgendaId 作为 AgendaId5_2_,this_.Description 作为 Descript3_5_2_,this_.OutcomeType 作为 OutcomeT4_5_2_,this_.OutcomeNumber 作为 OutcomeN5_5_2_,this_.Minutes 作为 Minutes5_2_,议程 1_.Id 作为 Id2_0_,议程 1_.LocationId 作为 LocationId2_0_议程 1_.日期为 Date2_0_,位置 2_.Id 为 Id7_1_,位置 2_.名称为 Name7_1_ FROM AgendaItem this_ left outer join 议程议程 1_ on this_.AgendaId=agenda1_.Id left outer join Location location2_ on avenue1_.LocationId=location2_.Id WHERE location2_.Id = ?和 (this_.Minutes like ? or this_.Description like ?) ORDER BY议程1_.Date asc, this_.OutcomeType asc, this_.OutcomeNumber asc] 位置参数:#0>1 #0>%Core% #0>%Core% [SQL:选择 this_.Id 作为 Id5_2_,this_.AgendaId 作为 AgendaId5_2_,this_.Description 作为 Descript3_5_2_,this_.OutcomeType 作为 OutcomeT4_5_2_,this_.OutcomeNumber 作为 OutcomeN5_5_2_,this_.Minutes 作为 Minutes5_2_,议程 1_.Id 作为 Id2_0_,议程 1_.LocationId 作为LocationId2_0_,agenda1_.Date as Date2_0_,location2_.Id as Id7_1_,location2_.Name as Name7_1_ FROM AgendaItem this_ left outer join Agenda议程1_ on this_.AgendaId=agenda1_.Id left external join Location location2_ on agenda1_.LocationId=location2_.Id WHERE location2_ .Id = ?和 (this_.Minutes like ? or this_.Description like ?) ORDER BY议程1_.Date asc, this_.OutcomeType asc, this_.OutcomeNumber asc]] NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +258 NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +18 NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) +87 NHibernate.Impl.SessionImpl.List(CriteriaImpl 标准,IList 结果)+342 NHibernate.Impl.CriteriaImpl.List(IList 结果) +41 NHibernate.Impl.CriteriaImpl.List() +35 C:\home\dev\tools\NHibernate\NHibernateContribSrc\src\NHibernate.Linq\src\NHibernate.Linq\CriteriaResultReader.cs:22 中的 NHibernate.Linq.CriteriaResultReader`1.List() C:\home\dev\tools\NHibernate\NHibernateContribSrc\src\NHibernate.Linq\src\NHibernate.Linq\CriteriaResultReader.cs:27 中的 NHibernate.Linq.d__0.MoveNext()

【问题讨论】:

【参考方案1】:

在我看来,这就像 Linq to Nhybernate 的一个错误。一种可能的解决方法是在排序之前转换为数组。一个潜在的大缺点是您无法在枚举之前使用 Skip() 和 Take() 限制结果,因此这对您来说可能还不够。

var results = items
   .ToArray()
   .OrderBy(item => item.Agenda.Date)
   .ThenBy(item => item.OutcomeType)
   .ThenBy(item => item.OutcomeNumber)
   .Skip((page - 1)*pageSize)
   .Take(pageSize)

【讨论】:

【参考方案2】:

虽然我不认为它会有所作为,但如果你像这样执行 linq 会发生什么:

(from i in items orderby i.prop1, i.prop2, i.prop3).Skip(...).Take(...).ToArray();

【讨论】:

是的,试过了,它最终被解析相同并给出相同的错误。【参考方案3】:

如果您的结果集相对较小,则首先将其转换为数组可能是一个可接受的解决方案。但是如果你想让 SQL Server 完成这项工作,你最好这样做:

var results = items
   .OrderBy(item => item.Agenda.Date).Asc
   .ThenBy(item => item.OutcomeType).Asc
   .ThenBy(item => item.OutcomeNumber).Asc
   .Skip((page - 1)*pageSize)
   .Take(pageSize)
   .ToArray();

每当您在 Linq 的 NHibernate 方言中使用 OrderBy 或 OrderByAlias 方法时,您应该始终添加 Asc 或 Desc 修饰符。

【讨论】:

以上是关于Linq to NHibernate 多个 OrderBy 调用的主要内容,如果未能解决你的问题,请参考以下文章

用 LINQ to SQL 或 LINQ to EF 替换 NHibernate

对于不支持子查询的 NHibernate-to-LINQ 是不是有任何解决方法?

NHibernate 或 LINQ to SQL [关闭]

有利于启动; Linq to SQL 还是 Nhibernate?

Linq To Nhibernate 性能优化(入门级)

不支持 linq to nhibernate compareto