我的代码如下:
class Program
{
static void Main(string[] args)
{
var testArr = new string[] { "b", "c" };
Func<A, bool> predicate = a => a.Name.Contains(testArr[0]) && a.Name.Contains(testArr[1]);
Console.Read();
}
}
public class A
{
public int Id { get; set; }
public string Name { get; set; }
}
代码中这个语句是写死的:
Func<A, bool> predicate = a => a.Name.Contains(testArr[0]) && a.Name.Contains(testArr[1]);
如何根据testArr动态生成呢。
注:查询表达式的格式是固定的,格式为:
a.Name.Contains(...) && a.Name.Contains(...)...
没看懂,你是说,predicate的body是由若干个a.Name.Contains和&&组成的(这个格式是固定的),但是predicate本身是要动态生成的?为什么会有这么奇怪的需求啊。而且你这里是Func<A, bool>,不是表达式树,也不会有解析之类的问题,为什么会有这么奇怪的限制呢。
var testArr = new string[] { "b", "c" };
var parameter = Expression.Parameter(typeof(A), "a");
var property = Expression.Property(parameter, "Name");
var contains = typeof(string).GetMethod("Contains");
var conditions = testArr.Select(s => Expression.Call(property, contains, Expression.Constant(s))).ToArray();
Expression condition = conditions[0];
for (int i = 1; i < conditions.Length; i++)
{
condition = Expression.And(condition, conditions[i]);
}
var predicate = Expression.Lambda(condition, parameter);
是这样的,示例代码中testArr的长度是不固定的
我在测试EF生成的SQL语句,有个地方需要用到这样的表达式
Func<A, bool>可以换成Expression<Func<A, bool>>类型,我用表达式树试过,没成功
@artwl: 看我修改后的答案。
@artwl: 最后结果是个LambdaExpression,如果你要Func,就compile一下。
@水牛刀刀: 谢谢啊,用compile不行啊,报错:
@水牛刀刀: 是不是我哪儿写错了啊
@artwl: Compile出来是个Delegate类型,你要cast一下。比如 as Func<A,bool>
@水牛刀刀: 可以了,非常感谢