Ejemplo n.º 1
0
        private FilterDefinition <BsonDocument> AnalysisConditionToFilterDefinition(int metaObjectId, List <SearchConditionAggregation> conditions, Dictionary <string, object> conditionValueDic, bool isIgnoreArgumentsCheck = false)
        {
            var bf = Builders <BsonDocument> .Filter;
            //全部字段字典缓存
            Dictionary <int, MetaField> metaFieldIdDic = metaFieldService.GetMetaFieldDicIdObjUnDeleted(metaObjectId);

            //获取全部条件表达式
            if (conditions == null || !conditions.Any())
            {
                return(null);
            }
            SearchConditionAggregation condition = conditions.FirstOrDefault(t => t.ParentId == -1);

            if (condition == null)
            {
                return(null);
            }

            //如果valueType==-1,则表明这个是连接条件
            if (condition.ValueType == -1)
            {
                //通过链接条件解析器进行解析
                return(ConditionRouter(condition));
            }
            //valueType!=-1 则表明这是个语句
            else
            {
                //通过条件表达式语句解析器解析
                return(ConditionValue(condition));
            }

            //连接条件解析器。如果是连接条件, 则执行下面逻辑将左...右子条件解析
            FilterDefinition <BsonDocument> ConditionRouter(SearchConditionAggregation routeCondition)
            {
                FilterDefinition <BsonDocument> filterDefinition = null;
                //将子节点全部取出
                var routeConditionChildren = conditions.Where(t => t.ParentId == routeCondition.Id).ToList();
                var first = routeConditionChildren.FirstOrDefault();

                if (first != null)
                {
                    //如果字节点是连接条件
                    if (first.ValueType == -1)
                    {
                        filterDefinition = ConditionRouter(first);
                    }
                    //如果是语句
                    else
                    {
                        filterDefinition = ConditionValue(first);
                        //根据根节点的连接条件执行不同的连接操作
                        switch (routeCondition.ConditionType)
                        {
                        case (int)ConditionJoint.And:
                            //子节点全部是与逻辑
                            foreach (var item in routeConditionChildren.Except(new[] { first }))
                            {
                                //如果valueType==-1 则表明是连接条件
                                if (item.ValueType == -1)
                                {
                                    var tempCondition = ConditionRouter(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.And(filterDefinition, tempCondition);
                                    }
                                }
                                //如果是表达式语句
                                else
                                {
                                    var tempCondition = ConditionValue(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.And(filterDefinition, tempCondition);
                                    }
                                }
                            }
                            break;

                        case (int)ConditionJoint.Or:
                            //子节点全部是或逻辑
                            foreach (var item in routeConditionChildren.Except(new[] { first }))
                            {
                                //如果valueType==-1 则表明是连接条件
                                if (item.ValueType == -1)
                                {
                                    var tempCondition = ConditionRouter(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.Or(filterDefinition, tempCondition);
                                    }
                                }
                                //如果是表达式语句
                                else
                                {
                                    var tempCondition = ConditionValue(item);
                                    if (tempCondition != null)
                                    {
                                        filterDefinition = bf.Or(filterDefinition, tempCondition);
                                    }
                                }
                            }
                            break;

                        default:
                            return(null);
                        }
                    }
                    return(filterDefinition);
                }
                return(null);
            }

            //条件值解析器
            FilterDefinition <BsonDocument> ConditionValue(SearchConditionAggregation routeCondition)
            {
                //如果条件值来自参数,则从参数列表里面获取
                if (routeCondition.Value.Equals("?"))
                {
                    //从参数获取到值
                    string key      = routeCondition.FieldCode;
                    var    keyUpper = key.ToUpperInvariant();
                    //如果没有传递参数值,则抛出异常
                    if (!conditionValueDic.ContainsKey(keyUpper))
                    {
                        //如果忽略参数检查,则直接返回null
                        if (isIgnoreArgumentsCheck)
                        {
                            return(null);
                        }
                        //如果不忽略参数检查,则抛出异常
                        else
                        {
                            throw new ArgumentNullException(key, $"Conditions define field parameters [{key}] but do not provide values.");
                        }
                    }
                    object argumentValue = conditionValueDic.SafeGet(keyUpper);
                    //将值转化为字段同类型的类型值
                    object value = metaFieldService.CheckAndGetFieldValueByFieldType(metaFieldIdDic[routeCondition.FieldId], argumentValue).Data;
                    switch (routeCondition.ConditionType)
                    {
                    case (int)ConditionType.Equal:
                        return(bf.Eq(key, value));

                    case (int)ConditionType.GreaterThan:
                        return(bf.Gt(key, value));

                    case (int)ConditionType.GreaterThanEqual:
                        return(bf.Gte(key, value));

                    case (int)ConditionType.LessThan:
                        return(bf.Lt(key, value));

                    case (int)ConditionType.LessThanEqual:
                        return(bf.Lte(key, value));

                    case (int)ConditionType.NotEqual:
                        return(bf.Ne(key, value));

                    default:
                        return(null);
                    }
                }
                //如果来自配置,则直接从配置里面获取到值
                else
                {
                    //校验字段以及转换字段值为目标类型
                    var convertResult = metaFieldService.CheckAndGetFieldValueByFieldType(metaFieldIdDic[routeCondition.FieldId], routeCondition.Value);
                    if (!convertResult.IsSuccess)
                    {
                        throw new ArgumentException("配置的字段值不符合字段的类型");
                    }

                    switch (routeCondition.ConditionType)
                    {
                    case (int)ConditionType.Equal:
                        return(bf.Eq(routeCondition.FieldCode, convertResult.Data));

                    case (int)ConditionType.GreaterThan:
                        return(bf.Gt(routeCondition.FieldCode, convertResult.Data));

                    case (int)ConditionType.GreaterThanEqual:
                        return(bf.Gte(routeCondition.FieldCode, convertResult.Data));

                    case (int)ConditionType.LessThan:
                        return(bf.Lt(routeCondition.FieldCode, convertResult.Data));

                    case (int)ConditionType.LessThanEqual:
                        return(bf.Lte(routeCondition.FieldCode, convertResult.Data));

                    case (int)ConditionType.NotEqual:
                        return(bf.Ne(routeCondition.FieldCode, convertResult.Data));

                    default:
                        return(null);
                    }
                }
            }
        }