Entity Framework 4 - простое внутреннее исключение Compiled Query при компиляции - PullRequest
2 голосов
/ 02 июня 2010

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

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.

Спасибо!

1 Ответ

2 голосов
/ 02 июня 2010

Посмотрим, исправит ли это:

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

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

...