我正在使用LINQ exprssion查询客户并按州名过滤它们。我有以下查询工作正常,直到我在statesArray中有4个项目。
public void GetCustomersForSelectedStates(string[] statesArray)
{
var customers = _repo.GetAllCustomers();
var filteredCustomers = from CUST in customers
join ST in States on CT.Tag_Id equals ST.Id
where CUST.ID == customer.ID && (ST.Name == statesArray[0] ||ST.Name ==statesArray[1] || ST.Name== statesArray[2]||ST.Name =statesArray[3])
//Do something with customers
}
我希望动态创建以下exprssion:
(ST.Name == statesArray[0] ||ST.Name ==statesArray[1] ||
ST.Name== statesArray[2]||ST.Name =statesArray[3])
例如,创建如下所示的dynamicQuery
var dynamicQuery = "(";
var dynamicQuery = "(";
for (int i = 0; i < statesArray.Count(); i++)
{
dynamicQuery += "ST.Name =="+statesArray[0];
if(i==statesArray.Count())
dynamicQuery+=")"
}
然后使用类似下面的内容,
//Psuedo code
var customers = _repo.GetAllCustomers();
var filteredCustomers = from CUST in customers
join ST in States on CT.Tag_Id equals ST.Id
where CUST.ID == customer.ID && Expression(dynamicQuery)
答案 0 :(得分:2)
通过动态表达式来实现 基本上意味着构建一个树:
(x.Foo == val0 || x.Foo == val1 || x.Foo == val2)
你可以这样做:
static Expression<Func<T, bool>> Where<T, TVal>(Expression<Func<T, TVal>> selector,
IEnumerable<TVal> values)
{
Expression result = null;
foreach (var val in values)
{
var match = Expression.Equal(
selector.Body,
Expression.Constant(val, typeof(TVal)));
result = result == null ? match : Expression.OrElse(result, match);
}
if (result == null) return x => true; // always match if no inputs
return Expression.Lambda<Func<T, bool>>(result, selector.Parameters);
}
示例用法:
string[] names = { "a", "c" };
var predicate = Where<Customer, string>(c => c.Name, names);
然后,您可以在predicate
扩展方法中使用此IQueryable<T>.Where
。
要结合您的情况,首先执行常规 LINQ:
var customers = _repo.GetAllCustomers();
var filteredCustomers = from CUST in customers
join ST in States on CT.Tag_Id equals ST.Id
where CUST.ID == customer.ID;
现在作为一个单独的步骤应用额外的过滤器:
customers = customers.Where(predicate);
这样做是接受c => c.Name
形式的输入 lambda,然后为每个c.Name
重用c.Name == {val}
正文 ,并重用c
参数作为我们正在创建的lambda的参数。 values
中的每个值都成为一个类型常量。 Expression.Equal
为我们提供了==
测试。 OrElse
是||
,注意如果result
是null
,则这是第一个项,因此我们只使用匹配表达式本身
答案 1 :(得分:1)
您可以添加其他加入
var customers = _repo.GetAllCustomers();
var filteredCustomers = from CUST in customers
join ST in States on CT.Tag_Id equals ST.Id
join SA in statesArray on ST.Name equals SA // No need dynamic expression now
where CUST.ID == customer.ID
//Do something with customers