Как спроецировать список с помощью QueryOver в NHibernate

#c# #nhibernate #queryover

#c# #nhibernate #запрос

Вопрос:

Я немного озадачен (или, скорее, глуп), когда дело доходит до QueryOver в NHibernate.

Я пытаюсь сделать что-то вроде этого:

 _session.QueryOver<Task>()
    .Where(x => x.Category == category)
    .Fetch(x => x.SubTasks).Eager
    .Select(
        x => x.Id,
        x => x.DisplayName,
        x => x.SubTasks)
    .List<object[]>();
  

Который, как я ожидаю, вернет мне список массивов объектов с моим идентификатором, DisplayName и набором каких-то загруженных подзадач.

Вместо этого я получаю следующее исключение:

 NHibernate.Exceptions.GenericADOException: could not execute query
[ SELECT this_.Id as y0_, this_.DisplayName as y1_, this_.Id as y2_ FROM [Task] this_ WHERE this_.Category = @p0 ]
Positional parameters:  #0>Internal
[SQL: SELECT this_.Id as y0_, this_.DisplayName as y1_, this_.Id as y2_ FROM [Task] this_ WHERE this_.Category = @p0] ---> System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at NHibernate.Loader.Criteria.CriteriaLoader.GetResultColumnOrRow(Object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) in d:CSharpNHNHnhibernatesrcNHibernateLoaderCriteriaCriteriaLoader.cs:line 111
   at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in d:CSharpNHNHnhibernatesrcNHibernateLoaderLoader.cs:line 479
   at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in d:CSharpNHNHnhibernatesrcNHibernateLoaderLoader.cs:line 243
   at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) in d:CSharpNHNHnhibernatesrcNHibernateLoaderLoader.cs:line 1694
   --- End of inner exception stack trace ---
   at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) in d:CSharpNHNHnhibernatesrcNHibernateLoaderLoader.cs:line 1711
   at NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) in d:CSharpNHNHnhibernatesrcNHibernateLoaderLoader.cs:line 1601
   at NHibernate.Loader.Criteria.CriteriaLoader.List(ISessionImplementor session) in d:CSharpNHNHnhibernatesrcNHibernateLoaderCriteriaCriteriaLoader.cs:line 74
   at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) in d:CSharpNHNHnhibernatesrcNHibernateImplSessionImpl.cs:line 1928
   at NHibernate.Impl.CriteriaImpl.List(IList results) in d:CSharpNHNHnhibernatesrcNHibernateImplCriteriaImpl.cs:line 265
   at NHibernate.Impl.CriteriaImpl.List[T]() in d:CSharpNHNHnhibernatesrcNHibernateImplCriteriaImpl.cs:line 277
   at Codehouse.TimeRegistration.Web.Controllers.TimeRegistrationAjax.TimeRegistrationGetTasksController.Execute(String category) in E:TfsSourceCodehouse Time Registration BeetleMainSourceCodehouse.TimeRegistration.Web.ControllersTimeRegistrationAjaxTimeRegistrationGetTasksControllers.cs:line 26
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  

Я потратил добрый час на поиск в Google, но безрезультатно — так что любая помощь / указатель будут высоко оценены.

Ответ №1:

Попробуйте

 _session.QueryOver<Task>()
    .Where(x => x.Category == category)
    .Fetch(x => x.SubTasks).Eager
    .List<Task>()
    .Select(
        x => x.Id,
        x => x.DisplayName,
        x => x.SubTasks)
     .ToList();
  

Я обнаружил, что это работает, создав список, а затем выполнив выбор после.