如何声明 Linq 表达式变量以便将其作为 dbParameter 处理
Posted
技术标签:
【中文标题】如何声明 Linq 表达式变量以便将其作为 dbParameter 处理【英文标题】:How to declare a Linq Expression variable in order to have it processed as a dbParameter 【发布时间】:2014-08-03 00:03:07 【问题描述】:我正在尝试针对实体框架(或其他 Linq 提供程序)创建动态查询。
让我用一些示例代码来解释我的问题。
如果我硬编码一个表达式:
var id = 12345;
Expression<Func<ItemSearch, bool>> myLambda = (s) => s.Id == id;
var finalQuery = context.ItemSearch.Where(myLambda);
this.Log((finalQuery as ObjectQuery).ToTraceString());
生成的 SQL 如下所示:
SELECT ...
FROM ViewItemSearch "Extent1"
WHERE "Extent1".ID = :p__linq__0
带有漂亮的:p__linq__0
dbParameter。
如果我创建一个表达式:
var id = 12345;
ParameterExpression param = Expression.Parameter(typeof(ItemSearch), "s");
Expression prop = Expression.Property(param, "Id");
Expression val = Expression.Constant(id);
Expression searchExpr = Expression.Equal(prop, val);
Expression<Func<ItemSearch, bool>> myLambda =
Expression.Lambda<Func<ItemSearch, bool>>(searchExpr , param);
var finalQuery = context.ItemSearch.Where(myLambda);
this.Log((finalQuery as ObjectQuery).ToTraceString());
生成的 SQL 如下所示:
SELECT ...
FROM ViewItemSearch "Extent1"
WHERE "Extent1".ID = 12345
没有更多的:p__linq__0
dbParameter,因此 Db 引擎无法缓存查询计划。
我明白是因为我用了
Expression val = Expression.Constant(id);
但我不知道如何绑定变量而不是值。
【问题讨论】:
我觉得你的问题有点令人困惑。如果要动态添加AND
逻辑条件,只需声明IQueryable
并动态追加.Where(i => yourPredicate)
即可。请参阅:***.com/questions/11189826/… 如果您想应用 OR
逻辑,您将需要这样的方法:albahari.com/nutshell/predicatebuilder.aspx
'or' 和 'and' 表达式工作得很好。问题在于参数的绑定。也许我应该编辑问题并删除结尾。这只是为了上下文。
【参考方案1】:
您需要在编译时创建一个 lambda 以关闭 id
变量,然后您可以在其中获取一个使用的主体以组成更复杂的 lambda:
var id = 12345;
ParameterExpression param = Expression.Parameter(typeof(ItemSearch), "s");
Expression prop = Expression.Property(param, "Id");
Expression<Func<int>> idLambda = () => id;
Expression searchExpr = Expression.Equal(prop, idLambda.Body);
Expression<Func<ItemSearch, bool>> myLambda =
Expression.Lambda<Func<ItemSearch, bool>>(searchExpr, param);
【讨论】:
以上是关于如何声明 Linq 表达式变量以便将其作为 dbParameter 处理的主要内容,如果未能解决你的问题,请参考以下文章
Firebase Admin SDK 错误:表达式的类型为“void”。将其作为声明放在自己的行中