时光荏苒,2020年不觉中已成过去。2021刚刚开头,新的开始本应意气风发、本应有会当凌绝顶豪情壮志,再不济也该“鸿图霸业谈笑间”,且不管一入江湖是不是岁月摧的洒脱。很不幸,有些事情就是会突入其来,搞得你触不及防,什么心情都没有。但是我居然还是写下了这篇博客。。。。。。嗯,总算是有地方表达以我糟糕心情了。
本来是想解决一下合并两个Expression<Func<T, object>>类型的表达式的问题,比如:
Expression<Func<T, object>> exp1 = t => t.updateTime; Expression<Func<T, object>> exp2 = t => new {t.age, t.name};
合并为一个表达式:Expression<Func<T, object>> exp1 = t => new {t.age, t.name, t.updateTime};
之前尝试过一些办法(比如下图方法1和方法2,但是都失败了)也请教过一些大佬,都没有解决这个问题。于是我只能绕过这个问题用其他方法去实现了业务需求(在这里抛出这个问题,也希望能有人帮我解惑)
退而求其次
我通过解析出来表达式中指定的属性也能满足我的需求,下面是我的实现方式:
1 private static List<MemberInfo> SelectMembers(Expression properties)
3 if( properties.NodeType == ExpressionType.Convert)
5 List<MemberInfo> newArrMembers = new List<MemberInfo>
7 ((MemberExpression)((UnaryExpression)properties).Operand).Member
8 };
9 return newArrMembers;
10 }
11 else
12 {
13 var newExp = (NewExpression)properties;
14 if (newExp != null)
15 {
16 return newExp.Members.ToList();
17 }
18 else
19 {
20 var newArr = (NewArrayExpression)properties;
21 if (newArr != null)
22 {
23 List<MemberInfo> newArrMembers = new List<MemberInfo>();
24 foreach (var newArrExp in newArr.Expressions)
25 newArrMembers.AddRange(SelectMembers(newArrExp));
26 return newArrMembers.Distinct().ToList();
27 }
28 return null;
29 }
30 }
1 public override Task<bool> UpdateAsync(T model, Expression<Func<T, object>> properties)
3 var mem = properties.SelectMembers();
4 if (mem != null)
6 var sc = mem.Select(t => t.Name).ToArray();
7 if (!sc.Contains("Updatedtime")) throw new Exception("表达必须指定updatedtime字段");
8 if (sc.Contains("Createdtime")) throw new Exception("不允许更新的字段");
10 model.UpdatedTime = DateTime.Now;
11 return base.UpdateAsync(model, properties);
下面附上一些实用的扩展
1 using System;
2 using System.Collections.Generic;
3 using System.Dynamic;
4 using System.Linq;
5 using System.Linq.Expressions;
6 using System.Reflection;
8 namespace Syspetro.Core.Extensions
10 /// <summary>
11 /// 合并表达式 And Or Not扩展
12 /// </summary>
13 public static class ExpressionHelper
14 {
15 /// <summary>
16 /// 合并表达式 expr1 AND expr2
17 /// </summary>
18 /// <typeparam name="T"></typeparam>
19 /// <param name="expr1"></param>
20 /// <param name="expr2"></param>
21 /// <returns></returns>
22 public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
23 {
24 if (expr1 == null)
25 return expr2;
26 else if (expr2 == null)
27 return expr1;
28 ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
29 MyExpressionVisitor visitor = new MyExpressionVisitor(newParameter);
30 var left = visitor.Visit(expr1.Body);
31 var right = visitor.Visit(expr2.Body);
33 return Expression.Lambda<Func<T, bool>>(Expression.And(left, right), newParameter);
34 }
35 /// <summary>
36 /// 合并表达式 expr1 or expr2
37 /// </summary>
38 /// <typeparam name="T"></typeparam>
39 /// <param name="expr1"></param>
40 /// <param name="expr2"></param>
41 /// <returns></returns>
42 public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
43 {
44 if (expr1 == null)
45 return expr2;
46 else if (expr2 == null)
47 return expr1;
48 ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
49 MyExpressionVisitor visitor = new MyExpressionVisitor(newParameter);
51 var left = visitor.Visit(expr1.Body);
52 var right = visitor.Visit(expr2.Body);
53 var body = Expression.Or(left, right);
54 return Expression.Lambda<Func<T, bool>>(body, newParameter);
55 }
56 /// <summary>
57 /// 取反表达式
58 /// </summary>
59 /// <typeparam name="T"></typeparam>
60 /// <param name="expr"></param>
61 /// <returns></returns>
62 public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expr)
63 {
64 if (expr == null) return null;
65 var candidateExpr = expr.Parameters[0];
66 var body = Expression.Not(expr.Body);
68 return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
69 }
70 /// <summary>
71 /// 获取表达式属性列表
72 /// </summary>
73 /// <typeparam name="T"></typeparam>
74 /// <param name="expr"></param>
75 /// <returns></returns>
76 public static List<MemberInfo> SelectMembers<T>(this Expression<Func<T, object>> expr)
77 {
78 return SelectMembers(expr.Body);
79 }
80 private static List<MemberInfo> SelectMembers(Expression properties)
81 {
82 if( properties.NodeType == ExpressionType.Convert)
83 {
84 List<MemberInfo> newArrMembers = new List<MemberInfo>
85 {
86 ((MemberExpression)((UnaryExpression)properties).Operand).Member
87 };
88 return newArrMembers;
89 }
90 else
91 {
92 var newExp = (NewExpression)properties;
93 if (newExp != null)
94 {
95 return newExp.Members.ToList();
96 }
97 else
98 {
99 var newArr = (NewArrayExpression)properties;
100 if (newArr != null)
101 {
102 List<MemberInfo> newArrMembers = new List<MemberInfo>();
103 foreach (var newArrExp in newArr.Expressions)
104 newArrMembers.AddRange(SelectMembers(newArrExp));
105 return newArrMembers.Distinct().ToList();
106 }
107 return null;
108 }
109 }
110 }
111 }
112 }
纵然此时你的内心是千疮百孔,万般无奈,那又怎样,你还想继续生活吗?那就只能继续前向,继续拼搏,努力让自己更加强大。所以该做的事情还是要做,加油。
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。