private Query VisitExpression(Expression expr, string prefix = null) { // Single: x.Active if (expr is MemberExpression && expr.Type == typeof(bool)) { return(Query.EQ(this.GetField(expr, prefix), new BsonValue(true))); } // Not: !x.Active or !(x.Id == 1) else if (expr.NodeType == ExpressionType.Not) { var unary = expr as UnaryExpression; return(Query.Not(this.VisitExpression(unary.Operand, prefix))); } // Equals: x.Id == 1 else if (expr.NodeType == ExpressionType.Equal) { var bin = expr as BinaryExpression; return(new QueryEquals(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // NotEquals: x.Id != 1 else if (expr.NodeType == ExpressionType.NotEqual) { var bin = expr as BinaryExpression; return(Query.Not(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // LessThan: x.Id < 5 else if (expr.NodeType == ExpressionType.LessThan) { var bin = expr as BinaryExpression; return(Query.LT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // LessThanOrEqual: x.Id <= 5 else if (expr.NodeType == ExpressionType.LessThanOrEqual) { var bin = expr as BinaryExpression; return(Query.LTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // GreaterThan: x.Id > 5 else if (expr.NodeType == ExpressionType.GreaterThan) { var bin = expr as BinaryExpression; return(Query.GT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // GreaterThanOrEqual: x.Id >= 5 else if (expr.NodeType == ExpressionType.GreaterThanOrEqual) { var bin = expr as BinaryExpression; return(Query.GTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // And: x.Id > 1 && x.Name == "John" else if (expr.NodeType == ExpressionType.AndAlso) { var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left, prefix); var right = this.VisitExpression(bin.Right, prefix); return(Query.And(left, right)); } // Or: x.Id == 1 || x.Name == "John" else if (expr.NodeType == ExpressionType.OrElse) { var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left); var right = this.VisitExpression(bin.Right); return(Query.Or(left, right)); } // MethodCall: x.Name.StartsWith("John") else if (expr is MethodCallExpression) { var met = expr as MethodCallExpression; var method = met.Method.Name; #if NET35 var type = met.Method.ReflectedType; #else var type = met.Method.DeclaringType; #endif var paramType = (met.Arguments[0] as MemberExpression)?.Expression.NodeType; // StartsWith if (method == "StartsWith") { var value = this.VisitValue(met.Arguments[0], null); return(Query.StartsWith(this.GetField(met.Object, prefix), value)); } // Equals else if (method == "Equals") { var value = this.VisitValue(met.Arguments[0], null); return(Query.EQ(this.GetField(met.Object, prefix), value)); } // Contains (String): x.Name.Contains("auricio") else if (method == "Contains" && type == typeof(string)) { var value = this.VisitValue(met.Arguments[0], null); return(Query.Contains(this.GetField(met.Object, prefix), value)); } // Contains (Enumerable): x.ListNumber.Contains(2) else if (method == "Contains" && type == typeof(Enumerable)) { var field = this.GetField(met.Arguments[0], prefix); var value = this.VisitValue(met.Arguments[1], null); return(Query.EQ(field, value)); } // Any (Enumerable): x.Customer.Any(z => z.Name.StartsWith("John")) else if (method == "Any" && type == typeof(Enumerable) && paramType == ExpressionType.Parameter) { var field = this.GetField(met.Arguments[0]); var lambda = met.Arguments[1] as LambdaExpression; return(this.VisitExpression(lambda.Body, field + ".")); } // System.Linq.Enumerable methods (constant list items) else if (type == typeof(Enumerable)) { return(ParseEnumerableExpression(met)); } } throw new NotImplementedException("Not implemented Linq expression"); }
private Query VisitExpression(Expression expr, string prefix = null) { try { // Single: x.Active if (expr is MemberExpression && expr.Type == typeof(bool)) { return(Query.EQ(this.GetField(expr, prefix), new BsonValue(true))); } // Not: !x.Active or !(x.Id == 1) else if (expr.NodeType == ExpressionType.Not) { var unary = expr as UnaryExpression; return(Query.Not(this.VisitExpression(unary.Operand, prefix))); } // Equals: x.Id == 1 else if (expr.NodeType == ExpressionType.Equal) { var bin = expr as BinaryExpression; return(new QueryEquals(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // NotEquals: x.Id != 1 else if (expr.NodeType == ExpressionType.NotEqual) { var bin = expr as BinaryExpression; return(Query.Not(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // LessThan: x.Id < 5 else if (expr.NodeType == ExpressionType.LessThan) { var bin = expr as BinaryExpression; return(Query.LT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // LessThanOrEqual: x.Id <= 5 else if (expr.NodeType == ExpressionType.LessThanOrEqual) { var bin = expr as BinaryExpression; return(Query.LTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // GreaterThan: x.Id > 5 else if (expr.NodeType == ExpressionType.GreaterThan) { var bin = expr as BinaryExpression; return(Query.GT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // GreaterThanOrEqual: x.Id >= 5 else if (expr.NodeType == ExpressionType.GreaterThanOrEqual) { var bin = expr as BinaryExpression; return(Query.GTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left))); } // And: x.Id > 1 && x.Name == "John" else if (expr.NodeType == ExpressionType.AndAlso) { var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left, prefix); var right = this.VisitExpression(bin.Right, prefix); return(Query.And(left, right)); } // Or: x.Id == 1 || x.Name == "John" else if (expr.NodeType == ExpressionType.OrElse) { var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left); var right = this.VisitExpression(bin.Right); return(Query.Or(left, right)); } // Constant: do nothing (at this point it's useful only to PredicateBuilder) else if (expr.NodeType == ExpressionType.Constant) { var constant = expr as ConstantExpression; if (constant.Value is bool) { var value = (bool)constant.Value; return(value ? Query.All() : new QueryEmpty()); } } // Invoke: call inner Lambda expression (used in PredicateBuilder) else if (expr.NodeType == ExpressionType.Invoke) { var invocation = expr as InvocationExpression; var lambda = invocation.Expression as LambdaExpression; return(this.VisitExpression(lambda.Body)); } // MethodCall: x.Name.StartsWith("John") else if (expr is MethodCallExpression) { var met = expr as MethodCallExpression; var method = met.Method.Name; // #if HAVE_TYPE_INFO var type = met.Method.DeclaringType; // #else // var type = met.Method.ReflectedType; // #endif var paramType = met.Arguments[0] is MemberExpression ? (ExpressionType?)(met.Arguments[0] as MemberExpression).Expression.NodeType : null; // StartsWith if (method == "StartsWith") { var value = this.VisitValue(met.Arguments[0], null); return(Query.StartsWith(this.GetField(met.Object, prefix), value)); } // Equals else if (method == "Equals") { var value = this.VisitValue(met.Arguments[0], null); return(Query.EQ(this.GetField(met.Object, prefix), value)); } // Contains (String): x.Name.Contains("auricio") else if (method == "Contains" && type == typeof(string)) { var value = this.VisitValue(met.Arguments[0], null); return(Query.Contains(this.GetField(met.Object, prefix), value)); } // Contains (Enumerable): x.ListNumber.Contains(2) else if (method == "Contains" && type == typeof(Enumerable)) { var field = this.GetField(met.Arguments[0], prefix); var value = this.VisitValue(met.Arguments[1], null); return(Query.EQ(field, value)); } // Any (Enumerable): x.Customer.Any(z => z.Name.StartsWith("John")) else if (method == "Any" && type == typeof(Enumerable) && paramType == ExpressionType.Parameter) { var field = this.GetField(met.Arguments[0]); var lambda = met.Arguments[1] as LambdaExpression; return(this.VisitExpression(lambda.Body, field + ".")); } // System.Linq.Enumerable methods (constant list items) else if (type == typeof(Enumerable)) { return(ParseEnumerableExpression(met)); } } return(new QueryLinq <T>(expr, _param, _mapper)); } catch (NotSupportedException) { // when there is no linq implementation, use QueryLinq return(new QueryLinq <T>(expr, _param, _mapper)); } }
private void EntityTracker_EntityUpdated(IEntity obj) { if (obj is UserEntity entity) { if (PacketProcessor.Instance.EntityTracker.CompassUser.Id != obj.Id) { if (Services.CompassSettings.MarkGuildAsAlly && entity.Relation == RelationType.PK && entity.GuildName == Services.CompassSettings.MyGuildName) { entity.Relation = RelationType.GuildMember; } PlayerModels[entity.Id] = entity; } } else if (Services.CompassSettings.ShowGatherting && obj is CollectionEntity collection) { CollectionModels[collection.Id] = collection; Task.Factory.StartNew(() => { try { CollectionEntity result = CollectionDatabase.Collection.FindOne(Query.And(Query.EQ("$.Position[0]", collection.Position.X), Query.EQ("$.Position[1]", collection.Position.Y), Query.EQ("$.Position[2]", collection.Position.Z))); if (result == null) { CollectionDatabase.Collection.Insert(collection); } } catch (Exception ex) { Trace.Write(ex.ToString()); } }); } }
private Query VisitExpression(Expression expr) { if (expr.NodeType == ExpressionType.Equal) // == { var bin = expr as BinaryExpression; return(new QueryEquals(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr is MemberExpression && expr.Type == typeof(bool)) // x.Active { return(Query.EQ(this.VisitMember(expr), new BsonValue(true))); } else if (expr.NodeType == ExpressionType.NotEqual) // != { var bin = expr as BinaryExpression; return(Query.Not(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr.NodeType == ExpressionType.Not) // !x.Active { var bin = expr as UnaryExpression; return(Query.EQ(this.VisitMember(bin), new BsonValue(false))); } else if (expr.NodeType == ExpressionType.LessThan) // < { var bin = expr as BinaryExpression; return(Query.LT(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr.NodeType == ExpressionType.LessThanOrEqual) // <= { var bin = expr as BinaryExpression; return(Query.LTE(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr.NodeType == ExpressionType.GreaterThan) // > { var bin = expr as BinaryExpression; return(Query.GT(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr.NodeType == ExpressionType.GreaterThanOrEqual) // >= { var bin = expr as BinaryExpression; return(Query.GTE(this.VisitMember(bin.Left), this.VisitValue(bin.Right))); } else if (expr is MethodCallExpression) { var met = expr as MethodCallExpression; var method = met.Method.Name; // StartsWith if (method == "StartsWith") { var value = this.VisitValue(met.Arguments[0]); return(Query.StartsWith(this.VisitMember(met.Object), value)); } // Contains else if (method == "Contains") { var value = this.VisitValue(met.Arguments[0]); return(Query.Contains(this.VisitMember(met.Object), value)); } // Equals else if (method == "Equals") { var value = this.VisitValue(met.Arguments[0]); return(Query.EQ(this.VisitMember(met.Object), value)); } } else if (expr is BinaryExpression && expr.NodeType == ExpressionType.AndAlso) { // AND var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left); var right = this.VisitExpression(bin.Right); return(Query.And(left, right)); } else if (expr is BinaryExpression && expr.NodeType == ExpressionType.OrElse) { // OR var bin = expr as BinaryExpression; var left = this.VisitExpression(bin.Left); var right = this.VisitExpression(bin.Right); return(Query.Or(left, right)); } throw new NotImplementedException("Not implemented Linq expression"); }
public string Select(string input) { if (!Opened) { return(JsonConvert.SerializeObject(new { ok = false, total = 0, count = 0, msg = "The model " + Model + " is closed" })); } long _total = Count(); string msg_field_null = JsonConvert.SerializeObject(new { ok = false, total = _total, count = 0, msg = "The data of QueryString is NULL. It has format: model=test&action=select&skip=0&limit=10&_op.1=eq&_id.1=8499849689d044a7a5b0ffe9&_andor.1=and&_op.2=eq&___dc.2=20180303" }); if (string.IsNullOrEmpty(input)) { return(msg_field_null); } //input = "model=test&action=select&skip=0&limit=10&" + // "f.1=_id&o.1=eq&v.1=b67cb5e92b6c45e0bab345b2" + // "&or=2.3" + // "&f.2=___dc&o.2=eq&v.2=20180303" + // "&f.3=___dc&o.3=eq&v.3=20180303"; var a = input.Split('&') .Select(x => x.Split('=')) .Where(x => x.Length > 1) .Select(x => new { key = x[0], value = x[1] }) .ToArray(); if (a.Length != a.Select(x => x.key).Distinct().ToArray().Length) { return(JsonConvert.SerializeObject(new { ok = false, total = _total, count = 0, msg = "The keys of QueryString duplicated" })); } string _or = a.Where(x => x.key == "or").Select(x => x.value).SingleOrDefault(); var ws = a .Where(x => x.key.Contains('.') && x.key.Split('.')[1].IsNumeric()) .Select(x => new QueryItem(x.key.Split('.')[0], int.Parse(x.key.Split('.')[1]), x.value, _or)) .ToArray(); int[] aCmdOR = ws.Where(x => x.isOr).Select(x => x.cmd).Distinct().ToArray(); QueryBuilder _query = null; List <Query> lsOr = new List <Query>() { }; for (int i = 0; i < aCmdOR.Length; i++) { var ai = ws.Where(x => x.cmd == aCmdOR[i]).ToArray(); string _field = ai.Where(x => x.field == "f").Select(x => x.value).SingleOrDefault(); string _operator = ai.Where(x => x.field == "o").Select(x => x.value).SingleOrDefault(); string _value = ai.Where(x => x.field == "v").Select(x => x.value).SingleOrDefault(); if (string.IsNullOrEmpty(_field) || string.IsNullOrEmpty(_operator)) { return(msg_field_null); } _query = convertQuery(_field, _operator, _value); if (_query.Ok && _query.Query != null) { lsOr.Add(_query.Query); } else { return(JsonConvert.SerializeObject(new { ok = false, total = _total, count = 0, msg = _query.Msg })); } } int[] aCmdAnd = ws.Where(x => x.isOr == false).Select(x => x.cmd).Distinct().ToArray(); List <Query> lsAnd = new List <Query>() { }; for (int i = 0; i < aCmdAnd.Length; i++) { var ai = ws.Where(x => x.cmd == aCmdAnd[i]).ToArray(); string _field = ai.Where(x => x.field == "f").Select(x => x.value).SingleOrDefault(); string _operator = ai.Where(x => x.field == "o").Select(x => x.value).SingleOrDefault(); string _value = ai.Where(x => x.field == "v").Select(x => x.value).SingleOrDefault(); if (string.IsNullOrEmpty(_field) || string.IsNullOrEmpty(_operator)) { return(msg_field_null); } _query = convertQuery(_field, _operator, _value); if (_query.Ok && _query.Query != null) { lsAnd.Add(_query.Query); } else { return(JsonConvert.SerializeObject(new { ok = false, total = _total, count = 0, msg = _query.Msg })); } } Dictionary <string, BsonDocument> dicStore = new Dictionary <string, BsonDocument>() { }; IEnumerable <KeyValuePair <string, BsonDocument> > rsFind; switch (lsOr.Count) { case 0: break; case 1: rsFind = _engine.FindCacheIDs(_LITEDB_CONST.COLLECTION_NAME, lsOr[0]).ToArray(); foreach (var kv in rsFind) { if (!dicStore.ContainsKey(kv.Key)) { dicStore.Add(kv.Key, kv.Value); } } break; default: rsFind = _engine.FindCacheIDs(_LITEDB_CONST.COLLECTION_NAME, Query.Or(lsOr.ToArray())).ToArray(); foreach (var kv in rsFind) { if (!dicStore.ContainsKey(kv.Key)) { dicStore.Add(kv.Key, kv.Value); } } break; } switch (lsAnd.Count) { case 0: break; case 1: rsFind = _engine.FindCacheIDs(_LITEDB_CONST.COLLECTION_NAME, lsAnd[0]).ToArray(); foreach (var kv in rsFind) { if (!dicStore.ContainsKey(kv.Key)) { dicStore.Add(kv.Key, kv.Value); } } break; default: rsFind = _engine.FindCacheIDs(_LITEDB_CONST.COLLECTION_NAME, Query.And(lsAnd.ToArray())).ToArray(); foreach (var kv in rsFind) { if (!dicStore.ContainsKey(kv.Key)) { dicStore.Add(kv.Key, kv.Value); } } break; } var jobject = a.Where(x => !x.key.Contains(".")) .GroupBy(x => x.key).Select(x => x.First()) .ToDictionary(x => x.key, x => x.value); string skip, limit; jobject.TryGetValue("skip", out skip); jobject.TryGetValue("limit", out limit); long _skip = 0; long _limit = 0; long.TryParse(skip, out _skip); long.TryParse(limit, out _limit); if (_skip < 0) { _skip = _LITEDB_CONST._SKIP; } if (_limit <= 0) { _limit = _LITEDB_CONST._LIMIT; } string[] allID = dicStore.Keys.ToArray(); string[] idRs = allID.Skip(_skip).Take(_limit).ToArray(); List <string> result = new List <string>(); foreach (string id in idRs) { result.Add(dicStore[id].toJson); } //var result = _engine // //.Find(_LITEDB_CONST.COLLECTION_NAME, Query.In(_LITEDB_CONST.FIELD_ID, idRs)) // .Find(_LITEDB_CONST.COLLECTION_NAME, Query.Where(_LITEDB_CONST.FIELD_ID, _id => listID.IndexOf(_id) != -1)) // .Select(x => x.toJson).ToArray(); return(@"{""ok"":true,""total"":" + _total.ToString() + @",""count"":" + result.Count.ToString() + @",""items"":[" + string.Join(",", result.ToArray()) + @"]}"); }
/// <summary> /// Add new Query filter when query will be executed. This filter use database index /// </summary> public LiteQueryable <T> Where(Query query) { _query = _query == null ? query : Query.And(_query, query); return(this); }