Просмотр исходного кода

支持使用外部变量,支持ID搜索

Support Lambda
Dream 7 лет назад
Родитель
Сommit
75e20ae332
2 измененных файлов с 156 добавлено и 1 удалено
  1. 10 1
      Server/Model/Module/DB/DBCacheComponent.cs
  2. 146 0
      Server/Model/Module/DB/ExpressionVistor.cs

+ 10 - 1
Server/Model/Module/DB/DBCacheComponent.cs

@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
 using System.Threading.Tasks;
 
 namespace ETModel
@@ -135,6 +137,13 @@ namespace ETModel
 			return tcs.Task;
 		}
 
+		
+		public Task<List<ComponentWithId>> Get<T>(string collectionName, Expression<Func<T, bool>> func) where T : ComponentWithId
+		{
+			var vistor = new ExpressionVistor(func);
+			return GetJson(collectionName,vistor.Output);
+		}
+		
 		public Task<List<ComponentWithId>> GetJson(string collectionName, string json)
 		{
 			TaskCompletionSource<List<ComponentWithId>> tcs = new TaskCompletionSource<List<ComponentWithId>>();

+ 146 - 0
Server/Model/Module/DB/ExpressionVistor.cs

@@ -0,0 +1,146 @@
+using System;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Text;
+
+namespace ETModel
+{
+    public sealed class ExpressionVistor: ExpressionVisitor
+    {
+        private readonly StringBuilder Builder = new StringBuilder("{");
+
+        public string Output
+        {
+            get
+            {
+                return this.Builder.ToString();
+            }
+        }
+
+        private string         Variable;
+        private ExpressionType NodeType;
+
+        public ExpressionVistor(Expression node)
+        {
+            Visit(node);
+        }
+
+        protected override Expression VisitLambda<T>(Expression<T> node)
+        {
+            var lambda = base.VisitLambda(node);
+            this.Builder.Remove(this.Builder.Length - 1, 1); //Remove the Last Comma
+            this.Builder.Append("}");
+            return lambda;
+        }
+
+        protected override Expression VisitBinary(BinaryExpression node)
+        {
+            this.NodeType = node.NodeType;
+            return base.VisitBinary(node);
+        }
+
+        protected override Expression VisitMember(MemberExpression node)
+        {
+            switch (node.Expression.NodeType)
+            {
+                case ExpressionType.Constant:
+                case ExpressionType.MemberAccess:
+                {
+                    var cleanNode = GetMemberConstant(node);
+                    return VisitConstant(cleanNode);
+                }
+            }
+
+            if (node.Member.Name != nameof(ComponentWithId.Id))
+                this.Variable = node.Member.Name;
+            else
+                this.Variable = "_id";
+            return base.VisitMember(node);
+        }
+
+        private static ConstantExpression GetMemberConstant(MemberExpression node)
+        {
+            object value;
+            if (node.Member.MemberType == MemberTypes.Field)
+            {
+                value = GetFieldValue(node);
+            }
+            else if (node.Member.MemberType == MemberTypes.Property)
+            {
+                value = GetPropertyValue(node);
+            }
+            else
+            {
+                throw new NotSupportedException();
+            }
+            return Expression.Constant(value, node.Type);
+        }
+        
+        protected override Expression VisitConstant(ConstantExpression node)
+        {
+            this.Builder.Append(this.Variable);
+            bool flag = false;
+            if (this.NodeType == ExpressionType.Equal)
+            {
+                this.Builder.Append(":");
+            }
+            else if (this.NodeType == ExpressionType.GreaterThan)
+            {
+                this.Builder.Append(":{");
+                this.Builder.Append("$gt:");
+                flag = true;
+            }
+            else if (this.NodeType == ExpressionType.GreaterThanOrEqual)
+            {
+                this.Builder.Append(":{");
+                this.Builder.Append("$gte:");
+                flag = true;
+            }
+            else if (this.NodeType == ExpressionType.LessThan)
+            {
+                this.Builder.Append(":{");
+                this.Builder.Append("$lt:");
+                flag = true;
+            }
+            else if (this.NodeType == ExpressionType.LessThanOrEqual)
+            {
+                this.Builder.Append(":{");
+                this.Builder.Append("lte:");
+                flag = true;
+            }
+
+            this.Builder.Append(node.Value);
+            if (flag)
+                this.Builder.Append("}");
+            this.Builder.Append(",");
+            return base.VisitConstant(node);
+        }
+        
+        private static object GetFieldValue(MemberExpression node)
+        {
+            var fieldInfo = (FieldInfo)node.Member;
+
+            var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
+
+            return fieldInfo.GetValue(instance);
+        }
+
+        private static object GetPropertyValue(MemberExpression node)
+        {
+            var propertyInfo = (PropertyInfo)node.Member;
+
+            var instance = (node.Expression == null) ? null : TryEvaluate(node.Expression).Value;
+
+            return propertyInfo.GetValue(instance, null);
+        }
+        
+        private static ConstantExpression TryEvaluate(Expression expression)
+        {
+            if (expression.NodeType == ExpressionType.Constant)
+            {
+                return (ConstantExpression)expression;
+            }
+            throw new NotSupportedException();
+        }
+    }
+}