Я хочу получить одну страницу из отсортированной таблицы. Я хочу, чтобы сортировка и подкачка страниц выполнялись на сервере. Для этого я создал следующий скомпилированный запрос:
internal static readonly Func<MyEntities, string, int, int, IQueryable<Model.Message>> MessagesPagedSortedByDateQuery =
CompiledQuery.Compile((MyEntities db, string folderId, int pageSize, int pageIndex) =>
(
db.Messages.Where(m => m.FolderId == folderId).OrderBy(m => m.Date).Skip(pageSize * pageIndex).Take(pageSize)
));
Мне кажется, это очень простой запрос. Однако, когда я выполняю это со следующим утверждением:
var messages = MessageCompiledQueries.MessagesPagedSortedByDateQuery(myEntities, folderId, pageSize, pageIndex).ToList();
Я получаю следующее исключение из источника System.Data.Entity:
Число должно быть выражением DbConstantExpression или DbParameterReferenceExpression.
Имя параметра: count
С помощью этой трассировки стека:
в System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateSkip (вход DbExpressionBinding, IEnumerable'1 sortOrder, счетчик DbExpression)
в System.Data.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.Skip (вход DbExpressionBinding, IEnumerable'1 sortOrder, счетчик DbExpression)
в System.Data.Objects.ELinq.ExpressionConverter.OrderByLifter.ApplySortOrderToSkip (вход DbExpression, сортировка DbSortExpression, DbExpression k)
в System.Data.Objects.ELinq.ExpressionConverter.OrderByLifter.SortLifter.Skip (DbExpression k)
в System.Data.Objects.ELinq.ExpressionConverter.Skip (вход DbExpressionBinding, DbExpression skipCount)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SkipTranslator.TranslatePagingOperator (родитель ExpressionConverter, операнд DbExpression, количество DbExpression)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.PagingTranslator.TranslateUnary (родитель ExpressionConverter, операнд DbExpression, вызов MethodCallExpression)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, SequenceMethod sequenceMethod)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate (родительский объект ExpressionConverter, MethodCallExpression linq)
в System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate (родитель ExpressionConverter, выражение Linq)
в System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (Expression linq)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель ExpressionConverter, вызов MethodCallExpression, SequenceMethod sequenceMethod)
в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate (родительский объект ExpressionConverter, MethodCallExpression linq)
в System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate (родитель ExpressionConverter, выражение Linq)
в System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (Expression linq)
в System.Data.Objects.ELinq.ExpressionConverter.Convert ()
в System.Data.Objects.ELinq.CompiledELinqQueryState.GetExecutionPlan (Nullable'1 forMergeOption)
в System.Data.Objects.ObjectQuery'1.GetResults (Nullable'1 forMergeOption)
в System.Data.Objects.ObjectQuery'1.System.Collections.Generic.IEnumerable.GetEnumerator ()
в System.Collections.Generic.List'1..ctor (коллекция IEnumerable'1)
в System.Linq.Enumerable.ToList [TSource] (источник IEnumerable'1)
в MyApp.Data.Repository.MessageRepository.GetByFolder (String folderId, Int32 pageSize, Int32 pageIndex, String sortField) в C: \ Projects \ MyApp \ MyApp.Data \ Repository \ MessageRepository.cs: строка 40
в MyApp.WebClient.Controllers.FolderController.Messages (команда GridCommand, String folderId) в C: \ Projects \ MyApp \ MyApp.WebClient \ Controllers \ FolderController.cs: строка 53at lambda_method (Closure, ControllerBase, Object [])
в System.Web.Mvc.ActionMethodDispatcher.Execute (контроллер ControllerBase, параметры Object [])
в System.Web.Mvc.ReflectedActionDescriptor.Execute (ControllerContext controllerContext, IDictionary`2 параметры)
в System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (ControllerContext controllerContext, ActionDescriptor actionDescriptor, параметры IDictionary'2)
в System.Web.Mvc.ControllerActionInvoker. <> c__DisplayClassd.b__a ()
в System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (фильтр IActionFilter, предварительный контекст ActionExecutingContext, продолжение Func'1)
Похоже, исключение возникает при первой компиляции запроса. Если я уберу orderby из запроса, он будет работать нормально. Но, очевидно, я бы хотел, чтобы упорядочение и подкачка страниц происходили на сервере, поэтому я не хочу этого делать после получения полной таблицы. Это ошибка в структуре сущностей? Я не могу найти ничего об этом в Интернете. Кто-нибудь знает, как обойти это?
Я использую финальную версию .Net Framework 4 с Visual Studio 2010.
Спасибо!