2010-06-02 1 views
2

Я хочу получить одну страницу из отсортированной таблицы. Я хочу, чтобы сортировка и подкачка выполнялись на сервере. Для этого я создал следующий скомпилированный запрос:Entity Framework 4 простой компилируемый внутренний запрос запроса при компиляции

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. Имя параметра: кол-

С этой StackTrace:

на 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 count) в System.Data.Objects.ELinq.ExpressionConverter.OrderByLifter.ApplySortOrderToSkip (вход DbExpression, сортировка DbSortExpression, DbExpression k) в Sy stem.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, вызов методаCallExpression) в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (ExpressionCo nverter родитель, MethodCallExpression вызов, SequenceMethod sequenceMethod) на System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate (ExpressionConverter родитель, MethodCallExpression LinQ) в System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate (ExpressionConverter родитель, Expression LINQ) в System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression (Expression Linq) в System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate (ExpressionConverter родителя, MethodCallExpression вызова) в системе. Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate (родитель выражений ExpressionConverter, вызов методаCallExpression, последовательность SequenceMethodMethod) в System.Data.Objects.E Linq.ExpressionConverter.MethodCallTranslator.TypedTranslate (родитель ExpressionConverter, MethodCallExpression linq) в System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate (родитель ExpressionConverter, выражение linq) в System.Data.Objects.ELinq.ExpressionConverter. TranslateExpression (Выражение 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: строка 53 в 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 preContext, Func'1 продолжение)

Похоже, что исключение возникает при компиляции запроса в первый раз , Если я удалю orderby из запроса, он работает нормально. Но, очевидно, мне хотелось бы, чтобы на сервере происходило упорядочение и пейджинг, поэтому я не хочу этого делать после получения полной таблицы. Это ошибка в структуре сущности? Я не могу найти ничего об этом в Интернете. Кто-нибудь знает, как обойти это? Я использую окончательный выпуск .Net Framework 4 с Visual Studio 2010.

Спасибо!

ответ

2

Смотрите, если это фиксирует это:

internal static readonly Func<MyEntities, string, int, int, int, IQueryable<Model.Message>> 
    MessagesPagedSortedByDateQuery = 
     CompiledQuery.Compile((MyEntities db, string folderId, int pageSize, int pageIndex, int skipCount) => 
     (
      db.Messages.Where(m => m.FolderId == folderId).OrderBy(m => m.Date).Skip(skipCount).Take(pageSize) 
     )); 

Обратите внимание, что я изменил подпись. Это, очевидно, не идеальное решение, но я не видел, как вы используете это в контексте кода. Если это приведет вас к ошибке, вы можете настроить ее на что-то более полезное.

+0

Отлично! Это работает. Как вы сказали, это не идеально, но я просто счастлив, что есть обходной путь. Я совершенно поражен тем, что простой запрос, подобный этому, создает такую ​​проблему для структуры сущности, и очень сложно среднему разработчику определить, что проблема связана с умножением. – Carvellis