c# Expression 扩展[转]
标签:protect ado www ram dal ext 条件运算 ace 传递
一、简介
当查询比较复杂时,需要很多判断或者跨方法传递参数时使用
二、扩展类
1 ///
2 /// Expression表达式扩展操作类
3 /// 调用方法:repository.GetAll().AsExpandable().Where(predicate)
4 ///
5 public static class ExpressionExtensions
6 {
7 ///
8 /// 以特定的条件运行组合两个Expression表达式
9 ///
10 /// 表达式的主实体类型
11 /// 第一个Expression表达式
12 /// 要组合的Expression表达式
13 /// 组合条件运算方式
14 /// 组合后的表达式
15 public static Expression Compose(this Expression first, Expression second,
16 Func merge)
17 {
18 var map =
19 first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
20 var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
21 return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
22 }
23
24 ///
25 /// 以 Expression.AndAlso 组合两个Expression表达式
26 ///
27 /// 表达式的主实体类型
28 /// 第一个Expression表达式
29 /// 要组合的Expression表达式
30 /// 组合后的表达式
31 public static Expressionbool>> And(this Expressionbool>> first,
32 Expressionbool>> second)
33 {
34 return first.Compose(second, Expression.AndAlso);
35 }
36
37 ///
38 /// 以 Expression.OrElse 组合两个Expression表达式
39 ///
40 /// 表达式的主实体类型
41 /// 第一个Expression表达式
42 /// 要组合的Expression表达式
43 /// 组合后的表达式
44 public static Expressionbool>> Or(this Expressionbool>> first,
45 Expressionbool>> second)
46 {
47 return first.Compose(second, Expression.OrElse);
48 }
49
50 private class ParameterRebinder : ExpressionVisitor
51 {
52 private readonly Dictionary _map;
53
54 private ParameterRebinder(Dictionary map)
55 {
56 _map = map ?? new Dictionary();
57 }
58
59 public static Expression ReplaceParameters(Dictionary map,
60 Expression exp)
61 {
62 return new ParameterRebinder(map).Visit(exp);
63 }
64
65 protected override Expression VisitParameter(ParameterExpression node)
66 {
67 ParameterExpression replacement;
68 if (_map.TryGetValue(node, out replacement))
69 node = replacement;
70 return base.VisitParameter(node);
71 }
72 }
73 }
三、如何使用
1.关于引用
using System.Linq;
using System.Linq.Expressions;
using LinqKit;
还需要引入扩展类的命名空间
2.使用示例
1 Expressionbool>> pre;
2 pre = s => s.NickName.Contains("李");
3 pre = pre.Or(s => s.NickName.Contains("陈"));
4 pre = pre.And(s => s.CompanyId == "1");
5
6 var data = _userRepository.GetAll().AsExpandable().Where(pre);
评论