我遇到的情况是我使用的linq提供程序不支持.Contains方法在查询中生成WHERE IN子句。我正在寻找一种从要匹配的项目列表动态生成(Value = X OR Value = Y OR Value = Z)语句的方法。我还没有找到构建表达式树的好例子。
通常我会这样查询:
var names = new string[] { "name1", "name2", "name3" }
var matches = query.Where(x => names.Contains(x.Name));
到目前为止,我能找到的最接近的是使用 Dynamic Linq Library并构建一个要解释的字符串,但感觉有点过于hacky。
答案 0 :(得分:0)
你甚至不需要这样的外部库:
var names = new string[] { "name1", "name2", "name3" };
// Where MyClass is the type of your class
ParameterExpression par = Expression.Parameter(typeof(MyClass));
MemberExpression prop = Expression.Property(par, "Name");
Expression expression = null;
foreach (string name in names)
{
Expression expression2 = Expression.Equal(prop, Expression.Constant(name));
if (expression == null)
{
expression = expression2;
}
else
{
expression = Expression.OrElse(expression, expression2);
}
}
var query = ...; // Your query
if (expression != null)
{
// Where MyClass is the type of your class
var lambda = Expression.Lambda<Func<MyClass, bool>>(expression, par);
query = query.Where(lambda);
}
您可以使用属性Expression.OrElse
与其中一个Name
之间的比较来构建string
的连接。
在这种特殊情况下(3 string
s),从调试器查看时得到的Expression
是:
(((Param_0.Name == "name1") OrElse (Param_0.Name == "name2")) OrElse (Param_0.Name == "name3"))
答案 1 :(得分:0)
只是通过xanatos改进答案:
var names = new string[] { "name1", "name2", "name3" };
var query = ...; // Your query
if (names.Any())
{
// Where MyClass is the type of your class
ParameterExpression par = Expression.Parameter(typeof(MyClass));
MemberExpression prop = Expression.Property(par, "Name");
var expression=names
.Select(v => Expression.Equal(prop, Expression.Constant(v)))
.Aggregate(Expression.OrElse);
// Where MyClass is the type of your class
var lambda = Expression.Lambda<Func<MyClass, bool>>(expression, par);
query = query.Where(lambda);
}