Question

J'ai du mal à trier plusieurs champs dans ma requête Linq to NHibernate.Est-ce que quelqu'un sait ce qui ne va pas ou s'il existe une solution?

Code:

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);

J'ai essayé de remplacer ThenBy par plusieurs appels OrderBy.Même résultat.La méthode fonctionne très bien si je commente les deux appels ThenBy.

Erreur que je reçois :

    [SqlException (0x80131904): Invalid column name '__hibernate_sort_expr_0____hibernate_sort_expr_1__'.
    Invalid column name '__hibernate_sort_expr_0____hibernate_sort_expr_1__'.]
       System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1948826
       System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean 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: could not execute query
    [ SELECT this_.Id as Id5_2_, this_.AgendaId as AgendaId5_2_, this_.Description as Descript3_5_2_, this_.OutcomeType as OutcomeT4_5_2_, this_.OutcomeNumber as OutcomeN5_5_2_, this_.Minutes as Minutes5_2_, agenda1_.Id as Id2_0_, agenda1_.LocationId as LocationId2_0_, agenda1_.Date as Date2_0_, location2_.Id as Id7_1_, location2_.Name as Name7_1_ FROM AgendaItem this_ left outer join Agenda agenda1_ on this_.AgendaId=agenda1_.Id left outer join Location location2_ on agenda1_.LocationId=location2_.Id WHERE location2_.Id = ? and (this_.Minutes like ? or this_.Description like ?) ORDER BY agenda1_.Date asc, this_.OutcomeType asc, this_.OutcomeNumber asc ]
    Positional parameters:  #0>1 #0>%Core% #0>%Core%
    [SQL: SELECT this_.Id as Id5_2_, this_.AgendaId as AgendaId5_2_, this_.Description as Descript3_5_2_, this_.OutcomeType as OutcomeT4_5_2_, this_.OutcomeNumber as OutcomeN5_5_2_, this_.Minutes as Minutes5_2_, agenda1_.Id as Id2_0_, agenda1_.LocationId as LocationId2_0_, agenda1_.Date as Date2_0_, location2_.Id as Id7_1_, location2_.Name as Name7_1_ FROM AgendaItem this_ left outer join Agenda agenda1_ on this_.AgendaId=agenda1_.Id left outer join Location location2_ on agenda1_.LocationId=location2_.Id WHERE location2_.Id = ? and (this_.Minutes like ? or this_.Description like ?) ORDER BY agenda1_.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 criteria, IList results) +342
       NHibernate.Impl.CriteriaImpl.List(IList results) +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
       NHibernate.Linq.d__0.MoveNext() in C:\home\dev\tools\NHibernate\NHibernateContribSrc\src\NHibernate.Linq\src\NHibernate.Linq\CriteriaResultReader.cs:27
Était-ce utile?

La solution

Cela me ressemble à un bug avec Linq to NHybernate.Une solution possible consiste à convertir en tableau avant de trier.Un inconvénient potentiellement important est que vous ne pouvez pas limiter les résultats en utilisant Skip() et Take() avant d'énumérer, cela peut donc ne pas être suffisant pour vous.

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

Autres conseils

même si je ne pense pas que cela ferait une différence, que se passe-t-il si vous faites votre linq comme ceci :

(à partir de i dans l'ordre des éléments par i.prop1, i.prop2, i.prop3).Skip(...).Take(...).ToArray();

Le transformer d’abord en tableau pourrait être une solution acceptable si votre jeu de résultats est relativement petit.Mais si vous voulez que SQL Server fasse le travail, vous feriez mieux de procéder de cette façon :

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();

Vous devez toujours ajouter un modificateur Asc ou Desc par la suite chaque fois que vous utilisez la méthode OrderBy ou OrderByAlias ​​dans le dialecte NHibernate de Linq.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top