6

Linq から 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);

ThenBy を複数の OrderBy 呼び出しに置き換えてみました。同じ結果です。このメソッドは、2 つの 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_ として、agenda1_.Id を Id2_0_ として、agenda1_.LocationId を LocationId2_0_ として選択し、アジェンダ 1_.Date は Date2_0_、location2_.Id は Id7_1_、location2_.Name は Name7_1_ FROM AgendaItem this_ 左外部結合 Agenda agenda1_ on this_.AgendaId=agenda1_.Id 左外部結合= ? および (this_.Minutes like ? または 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_ として、agenda1_.Id を Id2_0_ として、agenda1_.LocationId として SELECT します。 LocationId2_0_、agenda1_.Date は Date2_0_、location2_.Id は Id7_1_、location2_.Name は Name7_1_ として名前 FROM AgendaItem this_ left outside join Agenda agenda1_ on this_.AgendaId=agenda1_.Id left outside join Location2_ on agenda1_.LocationId=location2_.Id WHERE location2_ .ID = ? および (this_.Minutes like ? または this_.Description like ?) ORDER BY 議題 1_.Date asc、this_.OutcomeType asc、this_.OutcomeNumber asc]]
       NHibernate.Loader.Loader.DoList(ISessionImplementor セッション、QueryParameters queryParameters) +258
       NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor セッション、QueryParameters queryParameters) +18
       NHibernate.Loader.Loader.List(ISessionImplementor セッション、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
       NHibernate.Linq.CriteriaResultReader`1.List() in C:\home\dev\tools\NHibernate\NHibernateContribSrc\src\NHibernate.Linq\src\NHibernate.Linq\CriteriaResultReader.cs:22
       C:\home\dev\tools\NHibernate\NHibernateContribSrc\src\NHibernate.Linq\src\NHibernate.Linq\CriteriaResultReader.cs:27 の NHibernate.Linq.d__0.MoveNext()
4

3 に答える 3

7

これは、Linq to NHybernate のバグのように思えます。考えられる回避策の 1 つは、並べ替えの前に配列に変換することです。潜在的に大きな欠点は、列挙する前に 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)
于 2008-09-17T19:27:40.423 に答える
0

違いがあるとは思いませんが、次のようにlinqを実行するとどうなりますか:

(アイテムの i から i.prop1、i.prop2、i.prop3 で順番に)。Skip(...).Take(...).ToArray();

于 2008-09-14T02:51:52.573 に答える
0

結果セットが比較的小さい場合は、最初に配列に変換することが許容される解決策になる可能性があります。ただし、SQL サーバーに仕事をさせたい場合は、次のようにすることをお勧めします。

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 修飾子を追加する必要があります。

于 2018-08-23T12:17:40.933 に答える