Linq - 不支持的重载用于使用谓词的查询运算符 'Where'
Linq - Unsupported overload used for query operator 'Where' using a Predicate
我正在尝试修复一些性能不佳的 Linq 查询,但我在使用 Linq 语法时遇到了问题。我比 Linq 更擅长 SQL。
当前的工作版本只使用联接,但这是低效的,因为它返回多行,然后将这些行区分。我想将连接转换为 EXISTS 子句。它几乎可以工作,但是当我将谓词添加到 Where 子句时会出现问题。代码编译但出现上述错误。 SO 上有类似错误消息的问题,但它们似乎都在处理略有不同的场景。
此代码有效:
query = from contact in query
where Context.TblJobToBrandLink.Join(Context.TblBrandSpends
//.Where(spendExpression)
.Where(x => x.IntBrandiD != 0),
x => x.IntBrandId,
y => y.IntBrandiD,
(x, y) => x
).Any(jobToBrand => jobToBrand.IntJobId == contact.IntJobId)
select contact;
所产生的SQL正是我所期望的。
如果我用 .Where(spendExpression) 取消注释行,我会收到不受支持的重载错误。
spendExpression 的类型为 Linq.Expressions.Expression>
它在使用连接的版本中有效:
query = from contact in query
join jobToBrand in Context.TblJobToBrandLink on contact.IntJobId equals jobToBrand.IntJobId
join brandSpend in Context.TblBrandSpends.Where(spendExpression) on jobToBrand.IntBrandId equals brandSpend.IntBrandiD
where brandSpend.IntBrandiD != 0
select contact;
有什么想法吗?
我可以在类似的查询表达式中重现它。异常的堆栈跟踪如下所示:
at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
at System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate)
...
at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
所以这是 LINQ-to-SQL 表达式访问者绊倒了一些意想不到的复杂性。这意味着这只是一个错误,您必须解决它。
有效的(在我的例子中)是直接使用表达式:
query = from contact in query
where Context.TblJobToBrandLink
.Join(Context.TblBrandSpends
.Where(x => ...) // spendExpression's Expression here
...
或将 Context.TblBrandSpends.Where(spendExpression).Where(x => x.IntBrandiD != 0)
部分置于查询之外:
var brandSpends = Context.TblBrandSpends
.Where(spendExpression)
.Where(x => x.IntBrandiD != 0);
query = from contact in query
where Context.TblJobToBrandLink
.Join(brandSpends,
x => x.IntBrandId,
y => y.IntBrandiD,
(x, y) => x)
.Any(jobToBrand => jobToBrand.IntJobId == contact.IntJobId)
select contact;
顺便说一下,它在 Entity Framework 中有效。
我正在尝试修复一些性能不佳的 Linq 查询,但我在使用 Linq 语法时遇到了问题。我比 Linq 更擅长 SQL。
当前的工作版本只使用联接,但这是低效的,因为它返回多行,然后将这些行区分。我想将连接转换为 EXISTS 子句。它几乎可以工作,但是当我将谓词添加到 Where 子句时会出现问题。代码编译但出现上述错误。 SO 上有类似错误消息的问题,但它们似乎都在处理略有不同的场景。
此代码有效:
query = from contact in query
where Context.TblJobToBrandLink.Join(Context.TblBrandSpends
//.Where(spendExpression)
.Where(x => x.IntBrandiD != 0),
x => x.IntBrandId,
y => y.IntBrandiD,
(x, y) => x
).Any(jobToBrand => jobToBrand.IntJobId == contact.IntJobId)
select contact;
所产生的SQL正是我所期望的。
如果我用 .Where(spendExpression) 取消注释行,我会收到不受支持的重载错误。
spendExpression 的类型为 Linq.Expressions.Expression
它在使用连接的版本中有效:
query = from contact in query
join jobToBrand in Context.TblJobToBrandLink on contact.IntJobId equals jobToBrand.IntJobId
join brandSpend in Context.TblBrandSpends.Where(spendExpression) on jobToBrand.IntBrandId equals brandSpend.IntBrandiD
where brandSpend.IntBrandiD != 0
select contact;
有什么想法吗?
我可以在类似的查询表达式中重现它。异常的堆栈跟踪如下所示:
at System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
at System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
at System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
at System.Data.Linq.SqlClient.QueryConverter.VisitWhere(Expression sequence, LambdaExpression predicate)
...
at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
所以这是 LINQ-to-SQL 表达式访问者绊倒了一些意想不到的复杂性。这意味着这只是一个错误,您必须解决它。
有效的(在我的例子中)是直接使用表达式:
query = from contact in query
where Context.TblJobToBrandLink
.Join(Context.TblBrandSpends
.Where(x => ...) // spendExpression's Expression here
...
或将 Context.TblBrandSpends.Where(spendExpression).Where(x => x.IntBrandiD != 0)
部分置于查询之外:
var brandSpends = Context.TblBrandSpends
.Where(spendExpression)
.Where(x => x.IntBrandiD != 0);
query = from contact in query
where Context.TblJobToBrandLink
.Join(brandSpends,
x => x.IntBrandId,
y => y.IntBrandiD,
(x, y) => x)
.Any(jobToBrand => jobToBrand.IntJobId == contact.IntJobId)
select contact;
顺便说一下,它在 Entity Framework 中有效。