c#的mongodb动态查询filter拼接

调试要看拼接的filter最终生成的mongodb查询语句的代码如下:

        //调试输出mognodb的查询语句
        var documentSerializer = MongoDB.Bson.Serialization.BsonSerializer.SerializerRegistry.GetSerializer<ClientInfo>();
        var renderedFilter = query.filter.Render(documentSerializer, MongoDB.Bson.Serialization.BsonSerializer.SerializerRegistry).ToString();
        Console.WriteLine(renderedFilter);

动态拼接filter查询条件的,我是通过Lambda表达式的表达式树解析过程中将查询条件插入到表达式树解析的字典中,同时生成filter查询条件,然后到LambdaQuery类中拼接mongodb的filter实现的动态条件查询

    public Dictionary<String, FilterDefinition<T>> filters = new Dictionary<String, FilterDefinition<T>>();//动态条件字典
//表达式数普通条件拼接
    public string BinaryExpressionHandler(Expression left, Expression right, ExpressionType type)
    {
        StringBuilder sb = new StringBuilder();
        //sb.Append("(");
        string needParKey = "=,>,<,>=,<=,<>";
        string leftPar = RouteExpressionHandler(left);
        string typeStr = ExpressionTypeCast(type);
        var isRight = needParKey.IndexOf(typeStr) > -1;
        string rightPar = RouteExpressionHandler(right, isRight);


        string appendLeft = leftPar;

        sb.Append(appendLeft);//字段名称

        if (rightPar.ToUpper() == "NULL")
        {
            if (typeStr == "=")
                rightPar = " IS NULL ";
            else if (typeStr == "<>")
                rightPar = " IS NOT NULL ";
        }
        else
        {
            // sb.Append(")");
            sb.Append(typeStr);
            //sb.Append("(");
        }
        sb.Append(rightPar);
        Console.WriteLine("left:"+leftPar+",right:"+rightPar+",typeStr:"+typeStr);
        //sb.Append(")");
        var builder = Builders<T>.Filter;
        FilterDefinition<T> d;
        switch (type)
        {
            case ExpressionType.Equal:
                d = builder.Eq(leftPar, rightPar.Replace("'",""));
                filters.Add(typeStr.Trim() + ":"+Guid.NewGuid(), d);
                break;
            case ExpressionType.NotEqual:
                d = builder.Eq(leftPar, rightPar.Replace("'", ""));
                filters.Add(typeStr.Trim() + ":" + Guid.NewGuid(), d);
                break;
            case ExpressionType.AndAlso:
                filters.Add(typeStr.Trim() + ":" + Guid.NewGuid(), null);
                break;
            case ExpressionType.OrElse:
                filters.Add(typeStr.Trim() + ":" + Guid.NewGuid(), null);
                break;

        }
        return sb.ToString();
    }

表达式树自定义查询方法的字典filter条件查询

        if (MethodName == "in")
        {
            object Temp_Vale = (MethodCall.Arguments[1] as ConstantExpression).Value;
            string Value = string.Format("{0}", Temp_Vale);
            object Name = (MethodCall.Arguments[0] as MemberExpression).Member.Name;
            string Result = string.Format("{0} IN ({1})", Name, Value);
            //mongodb查询条件拼接
            var builder = Builders<T>.Filter;
            FilterDefinition<T> d;
            var values=Value.Split(',');
            d = builder.In(Name.ToString(), values);
            filters.Add("Call" + ":" + Guid.NewGuid(), d);

            return Result;
        }

LambdaQuery最终动态查询filter拼接的代码:

    internal string FormatExpression(Expression<Func<T, bool>> expression)
    {
        string condition;
        var visitor = new ExpressionVisitor<T>();
        if (expression == null)
            return "";
        condition = visitor.RouteExpressionHandler(expression.Body);
        Console.WriteLine(JsonConvert.SerializeObject(visitor.filter));
        //filter = visitor.filter;
        //字典拼接
        var builder = Builders<T>.Filter;
        FilterDefinition<T> leftfilter = null;
        FilterDefinition<T> rightfilter = null;
        foreach (String key in visitor.filters.Keys)
        {
            String k = key.Substring(0, key.IndexOf(":"));
            if (k == "=" || k == "Call")
            {
                if (leftfilter == null)
                {
                    leftfilter = visitor.filters[key];
                }
                else
                {
                    rightfilter = visitor.filters[key];
                }

            }

            if (visitor.filters[key] == null)
            {
                if (k.Equals("AND"))
                {
                    if (rightfilter == null)
                    {
                        if (filter.Equals(Builders<T>.Filter.Empty))
                        {
                            filter = leftfilter;
                        }
                        else
                        {
                            filter = filter & leftfilter;
                        }
                    }
                    else
                    {
                        if (filter.Equals(Builders<T>.Filter.Empty))
                        {
                            filter = leftfilter & rightfilter;
                        }
                        else
                        {
                            filter = filter & leftfilter & rightfilter;
                        }

                    }
                }
                if (k.Equals("OR"))
                {
                    if (rightfilter == null)
                    {
                        if (filter.Equals(Builders<T>.Filter.Empty))
                        {
                            filter = leftfilter;
                        }
                        else
                        {
                            filter = builder.Or(filter ,leftfilter);
                        }
                    }
                    else
                    {
                        if (filter.Equals(Builders<T>.Filter.Empty))
                        {
                            filter = builder.Or(leftfilter,rightfilter);
                        }
                        else
                        {
                            filter = builder.Or(filter , builder.Or(leftfilter,rightfilter));
                        }
                    }
                }
                leftfilter = null;
                rightfilter = null;
            }

            Console.WriteLine(key + ":" + JsonConvert.SerializeObject(visitor.filters[key]));
        }
        return condition;
    }
赞(1) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏