Entity Framework 4简单编译查询编译时出现内部异常

发布于 2024-09-04 15:28:29 字数 4825 浏览 3 评论 0原文

我想从排序表中检索一页。我希望排序和分页在服务器上完成。为此,我创建了以下编译查询:

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 收到以下异常:

Count 必须是 DbConstantExpression 或 DbParameterReferenceExpression。 参数名称:计数

使用此堆栈跟踪:

在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输入,DbExpressionskipCount) 在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调用,SequenceMethodsequenceMethod) 在 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(表达式 linq) 在System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用) 在System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter父级,MethodCallExpression调用,SequenceMethodsequenceMethod) 在 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(表达式 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 源) 在 C:\Projects\MyApp\MyApp.Data\Repository\MessageRepository.cs 中的 MyApp.Data.Repository.MessageRepository.GetByFolder(StringfolderId、Int32 pageSize、Int32 pageIndex、String sortField):第 40 行 在 C:\Projects\MyApp\MyApp.WebClient\Controllers\FolderController.cs 中的 MyApp.WebClient.Controllers.FolderController.Messages(GridCommand 命令,字符串folderId):第 53 行 在 lambda_method( 闭包 , ControllerBase , Object[] ) 在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器,Object[] 参数) 在System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContextcontrollerContext,IDictionary`2个参数) 在System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContextcontrollerContext,ActionDescriptoractionDescriptor,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 一起使用。

谢谢!

I want to retrieve one page from a sorted table. I want the sorting and paging to be done on the server. For this I created the following compiled query:

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

This seems a very straightforward query to me. However, when I execute it with the following statement:

var messages = MessageCompiledQueries.MessagesPagedSortedByDateQuery(myEntities, folderId, pageSize, pageIndex).ToList();

I get the following exception from source System.Data.Entity:

Count must be a DbConstantExpression or a DbParameterReferenceExpression.
Parameter name: count

With this stacktrace:

at System.Data.Common.CommandTrees.ExpressionBuilder.Internal.ArgumentValidation.ValidateSkip(DbExpressionBinding input, IEnumerable'1 sortOrder, DbExpression count)
at System.Data.Common.CommandTrees.ExpressionBuilder.DbExpressionBuilder.Skip(DbExpressionBinding input, IEnumerable'1 sortOrder, DbExpression count)
at System.Data.Objects.ELinq.ExpressionConverter.OrderByLifter.ApplySortOrderToSkip(DbExpression input, DbSortExpression sort, DbExpression k)
at System.Data.Objects.ELinq.ExpressionConverter.OrderByLifter.SortLifter.Skip(DbExpression k)
at System.Data.Objects.ELinq.ExpressionConverter.Skip(DbExpressionBinding input, DbExpression skipCount)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SkipTranslator.TranslatePagingOperator(ExpressionConverter parent, DbExpression operand, DbExpression count)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.PagingTranslator.TranslateUnary(ExpressionConverter parent, DbExpression operand, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.UnarySequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod)
at System.Data.Objects.ELinq.ExpressionConverter.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TypedTranslator'1.Translate(ExpressionConverter parent, Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq)
at System.Data.Objects.ELinq.ExpressionConverter.Convert()
at System.Data.Objects.ELinq.CompiledELinqQueryState.GetExecutionPlan(Nullable'1 forMergeOption)
at System.Data.Objects.ObjectQuery'1.GetResults(Nullable'1 forMergeOption)
at System.Data.Objects.ObjectQuery'1.System.Collections.Generic.IEnumerable.GetEnumerator()
at System.Collections.Generic.List'1..ctor(IEnumerable'1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable'1 source)
at MyApp.Data.Repository.MessageRepository.GetByFolder(String folderId, Int32 pageSize, Int32 pageIndex, String sortField) in C:\Projects\MyApp\MyApp.Data\Repository\MessageRepository.cs:line 40
at MyApp.WebClient.Controllers.FolderController.Messages(GridCommand command, String folderId) in C:\Projects\MyApp\MyApp.WebClient\Controllers\FolderController.cs:line 53
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
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__DisplayClassd.b__a()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func'1 continuation)

It looks like the exception occurs when compiling the query for the first time. If I remove the orderby from the query it works just fine. But obviously I would like the ordering and paging to occur on the server, so I don't want to do that after retrieving the full table. Is this a bug in the entity framework? I can't find anything about it on the web. Does anybody know how to work around this?
I use the .Net Framework 4 final release with Visual Studio 2010.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡忘如思 2024-09-11 15:28:29

看看这是否可以解决问题:

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

请注意,我已经更改了签名。这显然不是一个理想的解决方案,但我还没有看到您如何在代码上下文中使用它。如果它帮助您解决了错误,您可以将其调整为更有用的内容。

See if this fixes it:

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

Note that I've changed the signature. This is obviously not an ideal solution, but I haven't seen how you're using this in the context of the code. If it gets you around the error, you can tweak it into something more useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文