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

我正在尝试针对Entity框架(或其他Linq提供程序)创建动态查询。

让我用一些示例代码解释我的问题。

如果我硬编码表达式:

var id = 12345; Expression<Func> 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> myLambda = Expression.Lambda<Func>(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); 

但我无法弄清楚如何绑定变量而不是值。

你需要在编译时创建一个lambda来关闭id变量,然后你可以在更复杂的lambda的组合中获取一个用法的主体:

 var id = 12345; ParameterExpression param = Expression.Parameter(typeof(ItemSearch), "s"); Expression prop = Expression.Property(param, "Id"); Expression> idLambda = () => id; Expression searchExpr = Expression.Equal(prop, idLambda.Body); Expression> myLambda = Expression.Lambda>(searchExpr, param);