示例#1
0
        /// <summary>
        /// 将表达式翻译为相应的连接条件
        /// </summary>
        /// <param name="binary">表达式</param>
        /// <param name="relationType">关系类型</param>
        private void GetJoin(BinaryExpression binary, PredicateType predicateType, JoinRelation joinRelation)
        {
            Check.IfNullOrZero(binary);

            var leftMember  = (MemberExpression)binary.Left;
            var rightMember = (MemberExpression)binary.Right;

            //表达式左右两边都不为常量时例如 xx.Id==yy.Id
            if (binary.Left.NodeType != ExpressionType.Constant && binary.Right.NodeType != ExpressionType.Constant)
            {
                var leftAliasName  = ExtractMember(leftMember);
                var rightAliasName = ExtractMember(rightMember);

                var relationTemplate = _options.TemplateBase.CreatePredicate(predicateType, $"{rightAliasName}.{rightMember.Member.Name}", $"{leftAliasName}.{leftMember.Member.Name}");
                AssignmentPredicateType(joinRelation, relationTemplate);
            }
            else if (binary.Left.NodeType == ExpressionType.Constant) //表达式左边为常量
            {
                var rightAliasName = ExtractMember(rightMember);
                var constant       = (ConstantExpression)binary.Left;
                var value          = Boolean.TryParse(constant.Value.ToString(), out var result) ? (result ? 1 : 0).ToString() : constant.Value;
                AssignmentPredicateType(joinRelation, _options.TemplateBase.CreatePredicate(predicateType, value + "", $"{rightAliasName}.{rightMember.Member.Name}"));
            }
            else if (binary.Right.NodeType == ExpressionType.Constant) //表达式的右边为常量
            {
                var leftAliasName = ExtractMember(leftMember);
                var constant      = (ConstantExpression)binary.Right;
                var value         = Boolean.TryParse(constant.Value.ToString(), out var result) ? (result ? 1 : 0).ToString() : constant.Value;
                AssignmentPredicateType(joinRelation, _options.TemplateBase.CreatePredicate(predicateType, $"{leftAliasName}.{leftMember.Member.Name}", value + ""));
            }
        }
示例#2
0
        internal void AddJoin <TModel, TJoin>(Expression <Func <TModel, TJoin, Boolean> > expression, JoinRelation joinRelation)
            where TModel : EntityBase, new()
            where TJoin : EntityBase, new()
        {
            Check.IfNullOrZero(expression);

            Expression   = expression;
            JoinRelation = joinRelation;
            MainTable    = typeof(TModel).GetEntityBaseAliasName().TableName;

            InitAliasNameMappers(ParseToAliasNames(expression).ToArray().ToArray());
        }
示例#3
0
        /// <summary>
        /// 创建连接关系
        /// </summary>
        /// <param name="joinRelation">连接类型</param>
        /// <param name="left">左语句</param>
        /// <param name="right">右语句</param>
        /// <returns></returns>
        internal String CreateJoin(JoinRelation joinRelation, String left, String right)
        {
            Check.IfNullOrZero(joinRelation);
            Check.IfNullOrZero(left);
            Check.IfNullOrZero(right);

            if (!JoinMapper.ContainsKey(joinRelation))
            {
                throw new ArgumentNullException($@"{joinRelation}不存在");
            }

            return(String.Format(JoinMapper[joinRelation], left, right));
        }
示例#4
0
 private void AssignmentPredicateType(JoinRelation joinRelation, String value)
 {
     if (String.IsNullOrEmpty(value))
     {
         return;
     }
     if (joinRelation == JoinRelation.NONE)
     {
         _statementResultBuilder.WhereStatement.Append($@" {value} ");
     }
     else
     {
         _statementResultBuilder.JoinStatement.Append($@" {value} ");
     }
 }
示例#5
0
        /// <summary>
        /// 创建谓词语句
        /// </summary>
        /// <param name="binary"></param>
        /// <param name="predicateType"></param>
        /// <param name="joinRelation"></param>
        private void CreatePredicate(BinaryExpression binary, PredicateType predicateType, JoinRelation joinRelation)
        {
            Check.IfNullOrZero(binary);
            var binaryExp = binary;

            if (joinRelation != JoinRelation.NONE)
            {
                GetJoin(binaryExp, predicateType, joinRelation);
            }
            else
            {
                _predicateTypeStack.Push(predicateType);

                //当表达式的左边和右边同时不为常量或者只有左边为常量的话,则从左到右解析表达式,否则从右到左解析表达式
                if ((binary.Left.NodeType != ExpressionType.Constant && binary.Right.NodeType != ExpressionType.Constant) || binary.Left.NodeType != ExpressionType.Constant)
                {
                    InternalProcess(binaryExp.Left, joinRelation);
                    InternalProcess(binaryExp.Right, joinRelation);
                }
                else
                {
                    InternalProcess(binaryExp.Right, joinRelation);
                    InternalProcess(binaryExp.Left, joinRelation);
                }
            }
        }
示例#6
0
        private void ProcessMethodCall(Expression expression, JoinRelation joinRelation)
        {
            Check.IfNullOrZero(expression);
            var methodCallExp = (MethodCallExpression)expression;
            var methodName    = methodCallExp.Method.Name;

            var        methodCallArguments = methodCallExp.Arguments;
            Expression argument;
            Expression obj;
            Type       argumentType;

            if (methodCallArguments.Count > 1)
            {
                argumentType = methodCallArguments[0].Type;
                argument     = methodCallArguments[1];
                obj          = methodCallArguments[0];
            }
            else
            {
                argumentType = methodCallExp.Object.Type;
                argument     = methodCallArguments[0];
                obj          = methodCallExp.Object;
            }

            PredicateType predicateType = default;

            if (methodName == "StartsWith")
            {
                predicateType = PredicateType.START_LIKE;
            }
            else if (methodName == "EndsWith")
            {
                predicateType = PredicateType.END_LIKE;
            }
            else if (methodName == "Contains")
            {
                if (argumentType == typeof(String))
                {
                    predicateType = PredicateType.FULL_LIKE;
                }
                else if (argumentType.IsCollection())
                {
                    predicateType = PredicateType.IN;
                }
            }
            else
            {
                throw new Exception("暂不支持的方法");
            }

            _predicateTypeStack.Push(predicateType);

            if (argumentType == typeof(String))
            {
                InternalProcess(obj, joinRelation);
                InternalProcess(argument, joinRelation);
            }
            else if (argumentType.IsCollection())
            {
                InternalProcess(argument, joinRelation);
                InternalProcess(obj, joinRelation);
            }
        }
示例#7
0
        /// <summary>
        /// 根据表达式构建出相应结果
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="joinRelation"></param>
        private void InternalProcess(Expression expression, JoinRelation joinRelation)
        {
            switch (expression.NodeType)
            {
            case ExpressionType.AndAlso:
            {
                var binaryExp = (BinaryExpression)expression;

                if (binaryExp.Left.NodeType != ExpressionType.Constant && binaryExp.Right.NodeType != ExpressionType.Constant)
                {
                    InternalProcess(binaryExp.Left, joinRelation);
                    AssignmentPredicateType(joinRelation, PredicateType.AND.ToString());
                    InternalProcess(binaryExp.Right, joinRelation);
                }
                else
                {
                    if (binaryExp.Left.NodeType != ExpressionType.Constant)
                    {
                        InternalProcess(binaryExp.Left, joinRelation);
                    }
                    else if (binaryExp.Right.NodeType != ExpressionType.Constant)
                    {
                        InternalProcess(binaryExp.Right, joinRelation);
                    }
                }

                break;
            }

            case ExpressionType.OrElse:
            {
                var binaryExp = (BinaryExpression)expression;
                InternalProcess(binaryExp.Left, joinRelation);
                AssignmentPredicateType(joinRelation, PredicateType.OR.ToString());
                InternalProcess(binaryExp.Right, joinRelation);
                break;
            }

            case ExpressionType.Call:
            {
                ProcessMethodCall(expression, joinRelation);
                break;
            }

            case ExpressionType.Constant:
            {
                var binaryExp = (ConstantExpression)expression;
                _statementResultBuilder.AddParameter(new MapperParameter(_parameterNameStack.Pop(), binaryExp.Value));
                break;
            }

            case ExpressionType.Equal:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.EQ, joinRelation);
                break;
            }

            case ExpressionType.GreaterThan:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.GT, joinRelation);
                break;
            }

            case ExpressionType.NotEqual:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.NQ, joinRelation);
                break;
            }

            case ExpressionType.GreaterThanOrEqual:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.GE, joinRelation);
                break;
            }

            case ExpressionType.LessThan:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.LT, joinRelation);
                break;
            }

            case ExpressionType.LessThanOrEqual:
            {
                var binaryExp = (BinaryExpression)expression;
                CreatePredicate(binaryExp, PredicateType.LE, joinRelation);
                break;
            }

            case ExpressionType.Lambda:
            {
                var lamdbaExp = (LambdaExpression)expression;
                if (lamdbaExp.NodeType == ExpressionType.Constant)
                {
                    break;
                }

                if (lamdbaExp.Body is BinaryExpression expression4)
                {
                    InternalProcess(expression4, joinRelation);
                }
                else if (lamdbaExp.Body is MemberExpression expression3)
                {
                    InternalProcess(expression3, joinRelation);
                }
                else if (lamdbaExp.Body is MethodCallExpression expression2)
                {
                    InternalProcess(expression2, joinRelation);
                }
                else if (lamdbaExp.Body is UnaryExpression expression1)
                {
                    InternalProcess(expression1, joinRelation);
                }
                break;
            }

            case ExpressionType.MemberAccess:
            {
                var memberExp = (MemberExpression)expression;
                if (memberExp.Expression.NodeType == ExpressionType.Parameter)
                {
                    if (_predicateTypeStack.Count == 0)
                    {
                        if (memberExp.Type == typeof(Boolean))
                        {
                            var parameterExp  = (ParameterExpression)memberExp.Expression;
                            var newMember     = Expression.MakeMemberAccess(parameterExp, parameterExp.Type.GetMember(memberExp.Member.Name)[0]);
                            var newExpression = Expression.Equal(newMember, Expression.Constant(true));
                            InternalProcess(newExpression, joinRelation);
                        }
                    }
                    else
                    {
                        var parameterExp      = (ParameterExpression)memberExp.Expression;
                        var internalAliasName = "";
                        if (!_aliasMapper.Any(a => a.Key == parameterExp.Type.GetEntityBaseAliasName().TableName&& a.Value == parameterExp.Type.GetEntityBaseAliasName().AliasName))
                        {
                            throw new ArgumentException($@"没有找到{parameterExp.Type.Name}所对应的形参");
                        }
                        internalAliasName = $@"{_aliasMapper.Where(w => w.Key == parameterExp.Type.GetEntityBaseAliasName().TableName && w.Value == parameterExp.Type.GetEntityBaseAliasName().AliasName).FirstOrDefault().Value.ToLower()}.";

                        var newParameterName = Guid.NewGuid().ToString().Replace("-", "");
                        AssignmentPredicateType(joinRelation, _options.TemplateBase.CreatePredicate(_predicateTypeStack.Pop(), $@"{internalAliasName}{memberExp.Member.Name}", $"@{newParameterName}"));
                        _parameterNameStack.Push(newParameterName);
                    }
                }
                else
                {
                    var getter = Expression.Lambda(memberExp).Compile();
                    _statementResultBuilder.AddParameter(new MapperParameter(_parameterNameStack.Pop(), getter.DynamicInvoke()));
                }
                break;
            }

            case ExpressionType.Not:
            {
                var memberExpression = (MemberExpression)((UnaryExpression)expression).Operand;
                var parameterExp     = (ParameterExpression)memberExpression.Expression;
                var newMember        = Expression.MakeMemberAccess(parameterExp, parameterExp.Type.GetMember(memberExpression.Member.Name)[0]);
                InternalProcess(Expression.NotEqual(newMember, Expression.Constant(true)), joinRelation);
                break;
            }

            case ExpressionType.Convert:
            {
                var exp = ((UnaryExpression)expression).Operand;
                InternalProcess(exp, joinRelation);
                break;
            }

            default:
            {
                throw new NotSupportedException($@"暂不支持的表达式操作:{expression.NodeType}");
            }
            }
        }