gpt4 book ai didi

c# - 在 LINQ 表达式异常中检测到循环

转载 作者:可可西里 更新时间:2023-11-01 08:55:22 24 4
gpt4 key购买 nike

我得到错误:

A cycle was detected in a LINQ expression.

ToList()在尝试执行以下操作时:

private IEnumerable<int> FilterIdsByClient(IEnumerable<int> entityIds)
{
entityIds =
MyObjectContext.CreateObjectSet<TEntity>()
.Where(x => x.ClientId == _clientId)
.Where(x => entityIds.Contains(x.Id))
.Select(x => x.Id);

return entityIds.ToList();
}

但这不会抛出任何异常并且工作正常:

private IEnumerable<int> FilterIdsByClient(IEnumerable<int> entityIds)
{
entityIds =
MyObjectContext.CreateObjectSet<TEntity>()
.Where(x => x.ClientId == _clientId)
.Where(x => entityIds.Contains(x.Id))
.Select(x => x.Id)
.ToList();

return entityIds;
}

(当然这是一个简化版)

有人知道为什么会发生这种奇怪的行为吗?

编辑:

这是堆栈跟踪:

   at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.Funcletize(Expression expression, Func`1& recompileRequired)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.InlineExpression(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.InlineObjectQuery(ObjectQuery inlineQuery, Type expressionType)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.InlineValue(Expression expression, Boolean recompileOnChange)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Linq.Expressions.EntityExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at System.Linq.Expressions.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression m)
at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Linq.Expressions.EntityExpressionVisitor.VisitLambda(LambdaExpression lambda)
at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Linq.Expressions.EntityExpressionVisitor.VisitUnary(UnaryExpression u)
at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Linq.Expressions.EntityExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at System.Linq.Expressions.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression m)
at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Linq.Expressions.EntityExpressionVisitor.VisitExpressionList(ReadOnlyCollection`1 original)
at System.Linq.Expressions.EntityExpressionVisitor.VisitMethodCall(MethodCallExpression m)
at System.Linq.Expressions.EntityExpressionVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.FuncletizingVisitor.Visit(Expression exp)
at System.Data.Objects.ELinq.Funcletizer.Funcletize(Expression expression, Func`1& recompileRequired)
at System.Data.Objects.ELinq.ExpressionConverter..ctor(Funcletizer funcletizer, Expression expression)
at System.Data.Objects.ELinq.ELinqQueryState.CreateExpressionConverter()
at System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at ...FilterIdsByClient...

编辑2:

应该注意,在这种情况下,IEnumerable<int> entityIds是来自 ajax 请求的列表,而不是来自某处的查询。

最佳答案

该行为看起来很奇怪,因为您没有正确考虑闭包语义。请参阅以下评论:

private IEnumerable<int> FilterIdsByClient(IEnumerable<int> entityIds) 
{
// The variable entityIds points to whatever was passed in: A List, according to the edited question.

entityIds = //this is an assignment, changing the referent of entityIds
MyObjectContext.CreateObjectSet<TEntity>()
.Where(x => x.ClientId == _clientId)
.Where(x => entityIds.Contains(x.Id)) //this lambda closes over the variable entityIds
.Select(x => x.Id);

// The query now has a reference to the *variable* entityIds, not to the object that entityIds pointed to originally.
// The value of entityIds has been changed; it now points to the query itself!
// The query is therefore operating on itself; this causes the "cycle detected" message.
// Because of delayed execution, the query is not executed until the next line of code:

return entityIds.ToList();
}

关于c# - 在 LINQ 表达式异常中检测到循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8658278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com