ExpressionVistor.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. var 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. var cleanNode = GetMemberConstant(node);
  43. return VisitConstant(cleanNode);
  44. }
  45. }
  46. if (node.Member.Name != nameof(ComponentWithId.Id))
  47. this.Variable = node.Member.Name;
  48. else
  49. this.Variable = "_id";
  50. return base.VisitMember(node);
  51. }
  52. private static ConstantExpression GetMemberConstant(MemberExpression node)
  53. {
  54. object value;
  55. if (node.Member.MemberType == MemberTypes.Field)
  56. {
  57. value = GetFieldValue(node);
  58. }
  59. else if (node.Member.MemberType == MemberTypes.Property)
  60. {
  61. value = GetPropertyValue(node);
  62. }
  63. else
  64. {
  65. throw new NotSupportedException();
  66. }
  67. return Expression.Constant(value, node.Type);
  68. }
  69. protected override Expression VisitConstant(ConstantExpression node)
  70. {
  71. this.Builder.Append(this.Variable);
  72. bool flag = false;
  73. if (this.NodeType == ExpressionType.Equal)
  74. {
  75. this.Builder.Append(":");
  76. }
  77. else if (this.NodeType == ExpressionType.GreaterThan)
  78. {
  79. this.Builder.Append(":{");
  80. this.Builder.Append("$gt:");
  81. flag = true;
  82. }
  83. else if (this.NodeType == ExpressionType.GreaterThanOrEqual)
  84. {
  85. this.Builder.Append(":{");
  86. this.Builder.Append("$gte:");
  87. flag = true;
  88. }
  89. else if (this.NodeType == ExpressionType.LessThan)
  90. {
  91. this.Builder.Append(":{");
  92. this.Builder.Append("$lt:");
  93. flag = true;
  94. }
  95. else if (this.NodeType == ExpressionType.LessThanOrEqual)
  96. {
  97. this.Builder.Append(":{");
  98. this.Builder.Append("lte:");
  99. flag = true;
  100. }
  101. this.Builder.Append(node.Value);
  102. if (flag)
  103. this.Builder.Append("}");
  104. this.Builder.Append(",");
  105. return base.VisitConstant(node);
  106. }
  107. private static object GetFieldValue(MemberExpression node)
  108. {
  109. var fieldInfo = (FieldInfo)node.Member;
  110. var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
  111. return fieldInfo.GetValue(instance);
  112. }
  113. private static object GetPropertyValue(MemberExpression node)
  114. {
  115. var propertyInfo = (PropertyInfo)node.Member;
  116. var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
  117. return propertyInfo.GetValue(instance, null);
  118. }
  119. private static ConstantExpression TryEvaluate(Expression expression)
  120. {
  121. if (expression.NodeType == ExpressionType.Constant)
  122. {
  123. return (ConstantExpression)expression;
  124. }
  125. throw new NotSupportedException();
  126. }
  127. }
  128. }