如何声明Linq表达式变量,以便将其作为dbParameter处理

本文关键字:处理 dbParameter 变量 何声明 声明 表达式 Linq | 更新日期: 2023-09-27 18:08:33

我正在尝试创建针对实体框架(或其他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);

但是我不知道如何绑定变量而不是值

如何声明Linq表达式变量,以便将其作为dbParameter处理

您需要在编译时创建一个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);