Expression<Func<Dealer, bool>> GetFilter()
{
Expression<Func<Dealer, bool>> f = (d) => 1 == 1;
var s = "";
if (QS["Province"] != null)
{
s = QS["Province"];
f = d => d.Address.Province.Equals(s);
}
if (QS["City"] != null)
{
s = QS["City"];
f = d => d.Address.City.Equals(s);
}
if (QS["NameStartWith"] != null)
{
s = QS["NameStartWith"];
f = d => d.DealerName.Substring(0, 1).ToUpper().Equals(s);
}
return f;
}
根据查询字符串,我想生成Expression,以便使用通用存储库从数据库中获取所有经销商。
这是代码
Expression<Func<Dealer, bool>> filter = GetFilter();
GenericRepository<Dealer> DealerRepository = new GenericRepository<Dealer>();
List<Dealer> Dealers = DealerRepository.Get(filter).ToList();
答案 0 :(得分:1)
我假设您使用this repository pattern?
问题是,您只有一个表达式变量(f)并且您正在覆盖其内容。因此查询字符串
省= ONCA&安培;市=多伦多
将执行类似
的操作s = QS["Province"];
f = d => d.Address.Province.Equals(s);
s = QS["City"];
f = d => d.Address.City.Equals(s);
但是f只包含最后指定的值。要以EF友好的方式组合Lamda-Expressions,您需要this MSDN post中的一些实用工具类:
public class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> _map;
public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
_map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (_map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
public static class Utility
{
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.And);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.Or);
}
}
现在您可以编写如下代码:
Expression<Func<string, bool>> filter = x => true;
filter = filter.And(x => x.Contains("a"));
filter = filter.And(x => x.Contains("b"));
filter = filter.Or(x => x.Contains("c"));
var compiled = filter.Compile();
Console.WriteLine(compiled.Invoke("aaa")); // False
Console.WriteLine(compiled.Invoke("abba")); // True
Console.WriteLine(compiled.Invoke("aac")); // True
或者在你的情况下:
Expression<Func<Dealer, bool>> GetFilter()
{
Expression<Func<Dealer, bool>> filter = x => true;
if (QS["Province"] != null)
{
var s = QS["Province"];
filter = filter.And(d => d.Address.Province.Equals(s));
}
if (QS["City"] != null)
{
var s = QS["City"];
filter = filter.And(d => d.Address.City.Equals(s));
}
if (QS["NameStartWith"] != null)
{
var s = QS["NameStartWith"];
filter = filter.And(d => d.DealerName.Substring(0, 1).ToUpper().Equals(s));
}
return filter;
}