سؤال

أواجه مشكلة في الطلب حسب أكثر من حقل واحد في استعلام 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 المتعددة.نفس النتيجة.تعمل الطريقة بشكل رائع إذا قمت بالتعليق على مكالمتي ThenBy.

الخطأ الذي أتلقاه:

    [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
هل كانت مفيدة؟

المحلول

يبدو لي أن هذا خطأ في Linq في 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)

نصائح أخرى

على الرغم من أنني لا أعتقد أن ذلك سيحدث فرقًا، ماذا يحدث إذا قمت بإجراء linq الخاص بك على النحو التالي:

(من i في ترتيب العناصر حسب i.prop1، i.prop2، i.prop3).Skip(...).Take(...).ToArray();

قد يكون تحويله أولاً إلى مصفوفة حلاً مقبولاً في حالة ما إذا كانت مجموعة النتائج صغيرة نسبيًا.ولكن إذا كنت تريد أن تجعل خادم 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();

يجب عليك دائمًا إضافة معدل Asc أو Desc بعد ذلك عندما تستخدم طريقة OrderBy أو OrderByAlias ​​في لهجة NHibernate الخاصة بـ Linq.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top