【发布时间】:2015-11-27 05:25:47
【问题描述】:
更新:2015 年 9 月 3 日
好的,我尝试使用 .Join 代替:
[System.Web.Http.HttpGet]
public IQueryable<RunOfferPublish> RunOfferPublishes()
{
var showIds = _showSecurityCache.GetRunIdsForCurrentUser().AsEnumerable();
return Context.RunOfferPublishes.Join(showIds, r => r.RunOffer.Run.showId, i => i, (r, i) => r);
}
我得到另一个异常,说我的查询嵌套很深。我做了一种方法来减少嵌套并改为获取 runIds。但是,还有更多的 id..
[System.Web.Http.HttpGet]
public IQueryable<RunOfferPublish> RunOfferPublishes()
{
var runIds = _showSecurityCache.GetRunIdsForCurrentUser().AsEnumerable();
return Context.RunOfferPublishes.Join(runIds, r => r.RunOffer.RunId, i => i, (r, i) => r);
}
我得到一个 stackoverflow 异常,有很多运行。
然后我尝试删除获取所有实体的列表,并在内存中执行位置。像这样:
[System.Web.Http.HttpGet]
public IQueryable<RunOfferPublish> RunOfferPublishes()
{
var showIds = _showSecurityCache.GetShowIdsForCurrentUser();
var list = Context.RunOfferPublishes.ToList();
return list.Where(i => showIds.Contains(i.RunOffer.Run.ShowId)).AsQueryable();
}
这“有效”,它返回实体列表。但是,我遇到了 Breeze 的问题
“System.Linq.EnumerableQuery”不包含“包含”的定义
at CallSite.Target(Closure , CallSite , Object , String )
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at CallSite.Target(Closure , CallSite , Object , String )
at Breeze.WebApi.QueryHelper.<>c__DisplayClass14.<ApplyExpand>b__11(String expand)
at System.Collections.Generic.List`1.ForEach(Action`1 action)
at Breeze.WebApi.QueryHelper.ApplyExpand(IQueryable queryable, String expandsQueryString)
at Breeze.WebApi.QueryHelper.ApplySelectAndExpand(IQueryable queryable, NameValueCollection map)
at Breeze.WebApi.BreezeQueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
at System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecuted(HttpActionContext actionContext, HttpResponseMessage response, Exception exception)
at System.Web.Http.Filters.ActionFilterAttribute.<>c__DisplayClass2.<System.Web.Http.Filters.IActionFilter.ExecuteActionFilterAsync>b__0(HttpResponseMessage response)
at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass41`2.<Then>b__40(Task`1 t)
at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[TTask,TOuterResult](TTask task, Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously)
因此,我仍然陷入困境。
----- 上面的问题更新----
我正在尝试调查此控制器方法的问题:
[System.Web.Http.HttpGet]
public IQueryable<RunOfferPublish> RunOfferPublishes()
{
var showIds = _showSecurityCache.GetShowIdsForCurrentUser();
var query = Context.RunOfferPublishes.Where(rop => showIds.Contains(rop.RunOffer.Run.ShowId)).AsQueryable();
return query;
}
showIds 数组是 212 个小整数(0 到 212)的列表。 RunOfferPublishes 是 DBContext(上下文)中的一个表
如果我删除了 .Where 查询正在运行,但它会引发内存不足异常。我试图查看生成的 SQL 是什么,但我认为它没有达到这一点,因为我没有通过 SQL Profiler 看到它。
例外:
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Collections.Generic.List`1.set_Capacity(Int32 value)
at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitJoinInput(Node joinInputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitBinaryJoin(Node joinNode, DbExpressionKind joinKind)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(LeftOuterJoinOp op, Node n)
at System.Data.Query.InternalTrees.LeftOuterJoinOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(FilterOp op, Node n)
at System.Data.Query.InternalTrees.FilterOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator.VisitAsRelOp(Node inputNode)
at System.Data.Query.PlanCompiler.CTreeGenerator.BuildProjection(Node relOpNode, IEnumerable`1 projectionVars)
at System.Data.Query.PlanCompiler.CTreeGenerator.Visit(PhysicalProjectOp op, Node n)
at System.Data.Query.InternalTrees.PhysicalProjectOp.Accept[TResultType](BasicOpVisitorOfT`1 v, Node n)
at System.Data.Query.InternalTrees.BasicOpVisitorOfT`1.VisitNode(Node n)
at System.Data.Query.PlanCompiler.CTreeGenerator..ctor(Command itree, Node toConvert)
at System.Data.Query.PlanCompiler.ProviderCommandInfoUtils.Create(Command command, Node node, List`1 children)
at System.Data.Query.PlanCompiler.CodeGen.Process(List`1& childCommands, ColumnMap& resultColumnMap, Int32& columnCount)
at System.Data.Query.PlanCompiler.PlanCompiler.Compile(List`1& providerCommands, ColumnMap& resultColumnMap, Int32& columnCount, Set`1& entitySets)
at System.Data.EntityClient.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree)
at System.Data.EntityClient.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree)
at System.Data.EntityClient.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree)
at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, ReadOnlyCollection`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery.ToTraceString()
at System.Data.Entity.Internal.Linq.InternalQuery`1.ToString()
at System.Data.Entity.Infrastructure.DbQuery`1.ToString()
at ******************MainController.RunOfferPublishes() in
【问题讨论】:
-
看起来好像您正在遍历三个表以查看一个 ID 是否包含在可能是一个大集合中,更糟糕的是,您似乎是在内存中执行此操作。我猜这是你的问题。
-
你确定它只有 212 个整数吗?您可以将其更改为:
var showIds = _showSecurityCache.GetShowIdsForCurrentUser().ToList()并验证吗?使用ToList表单时是否仍会出现OOM 异常? -
@Rob 是的,我调试了那部分。 GetShowIdsForCurrentUser() 返回一个列表。
-
@DavidL 是这样吗?前 2 个表有大约 5k 条记录,第三个和最后一个表少于 1k。
-
一切皆有可能,具体取决于您的表的配置方式。您无法发布查询,因此您的猜测肯定比我的要好:)
标签: c# entity-framework-4 breeze asp.net-web-api2 iqueryable