ExpressionVistor.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.Linq.Expressions;
  3. using System.Reflection;
  4. using System.Text;
  5. namespace ETModel
  6. {
  7. public sealed class ExpressionVistor: ExpressionVisitor
  8. {
  9. private readonly StringBuilder Builder = new StringBuilder("{");
  10. public string Output
  11. {
  12. get
  13. {
  14. return this.Builder.ToString();
  15. }
  16. }
  17. private string Variable;
  18. private ExpressionType NodeType;
  19. public ExpressionVistor(Expression node)
  20. {
  21. Visit(node);
  22. }
  23. protected override Expression VisitLambda<T>(Expression<T> node)
  24. {
  25. Expression lambda = base.VisitLambda(node);
  26. this.Builder.Remove(this.Builder.Length - 1, 1); //Remove the Last Comma
  27. this.Builder.Append("}");
  28. return lambda;
  29. }
  30. protected override Expression VisitBinary(BinaryExpression node)
  31. {
  32. this.NodeType = node.NodeType;
  33. return base.VisitBinary(node);
  34. }
  35. protected override Expression VisitMember(MemberExpression node)
  36. {
  37. switch (node.Expression.NodeType)
  38. {
  39. case ExpressionType.Constant:
  40. case ExpressionType.MemberAccess:
  41. {
  42. ConstantExpression cleanNode = GetMemberConstant(node);
  43. return VisitConstant(cleanNode);
  44. }
  45. }
  46. if (node.Member.Name != nameof(ComponentWithId.Id))
  47. {
  48. this.Variable = node.Member.Name;
  49. }
  50. else
  51. {
  52. this.Variable = "_id";
  53. }
  54. return base.VisitMember(node);
  55. }
  56. private static ConstantExpression GetMemberConstant(MemberExpression node)
  57. {
  58. object value;
  59. switch (node.Member.MemberType)
  60. {
  61. case MemberTypes.Field:
  62. value = GetFieldValue(node);
  63. break;
  64. case MemberTypes.Property:
  65. value = GetPropertyValue(node);
  66. break;
  67. default:
  68. throw new NotSupportedException();
  69. }
  70. return Expression.Constant(value, node.Type);
  71. }
  72. protected override Expression VisitConstant(ConstantExpression node)
  73. {
  74. this.Builder.Append(this.Variable);
  75. bool flag = false;
  76. switch (this.NodeType)
  77. {
  78. case ExpressionType.Equal:
  79. this.Builder.Append(":");
  80. break;
  81. case ExpressionType.GreaterThan:
  82. this.Builder.Append(":{");
  83. this.Builder.Append("$gt:");
  84. flag = true;
  85. break;
  86. case ExpressionType.GreaterThanOrEqual:
  87. this.Builder.Append(":{");
  88. this.Builder.Append("$gte:");
  89. flag = true;
  90. break;
  91. case ExpressionType.LessThan:
  92. this.Builder.Append(":{");
  93. this.Builder.Append("$lt:");
  94. flag = true;
  95. break;
  96. case ExpressionType.LessThanOrEqual:
  97. this.Builder.Append(":{");
  98. this.Builder.Append("lte:");
  99. flag = true;
  100. break;
  101. }
  102. this.Builder.Append(node.Value);
  103. if (flag)
  104. {
  105. this.Builder.Append("}");
  106. }
  107. this.Builder.Append(",");
  108. return base.VisitConstant(node);
  109. }
  110. private static object GetFieldValue(MemberExpression node)
  111. {
  112. FieldInfo fieldInfo = (FieldInfo)node.Member;
  113. object instance = node.Expression == null ? null : TryEvaluate(node.Expression).Value;
  114. return fieldInfo.GetValue(instance);
  115. }
  116. private static object GetPropertyValue(MemberExpression node)
  117. {
  118. PropertyInfo propertyInfo = (PropertyInfo)node.Member;
  119. object instance = node.Expression == null ? null : TryEvaluate(node.Expression).Value;
  120. return propertyInfo.GetValue(instance, null);
  121. }
  122. private static ConstantExpression TryEvaluate(Expression expression)
  123. {
  124. if (expression.NodeType != ExpressionType.Constant)
  125. {
  126. throw new NotSupportedException();
  127. }
  128. return (ConstantExpression)expression;
  129. }
  130. }
  131. }