/// <summary>
        /// 
        /// </summary>
        /// <param name="converter"></param>
        /// <param name="method"></param>
        /// <returns></returns>
        public override ExpressionElement Convert(IExpressionConverter converter, MethodCallExpression method)
        {
            var index = method.SkipMethodChain(0);
            var args = method.Arguments.Skip(index).Select(e => converter.Convert(e)).ToArray();
            var name = string.IsNullOrEmpty(Name) ? method.Method.Name.ToUpper() : Name;

            var hArgs = new HText(args) { Separator = Separator }.ConcatToBack(")");
            return new HText(Line(name, "("), hArgs) { IsFunctional = true };
        }
        public override ExpressionElement Convert(IExpressionConverter converter, MethodCallExpression method)
        {
            var arg = method.Arguments[method.SkipMethodChain(0)];
            var array = arg as NewArrayExpression;

            var orderBy = new VText();
            orderBy.Add("ORDER BY");
            var sort = new VText() { Separator = "," };
            sort.AddRange(1, array.Expressions.Select(e => converter.Convert(e)).ToList());
            orderBy.Add(sort);
            return orderBy;
        }
        /// <summary>
        /// Convert expression to code.
        /// </summary>
        /// <param name="expression">Expression.</param>
        /// <param name="converter">Expression converter.</param>
        /// <returns>Parts.</returns>
        public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter)
        {
            //ALL, DISTINCT, TOP
            int expressionIndex = expression.SkipMethodChain(0);
            var selectParts = new ICode[expression.Arguments.Count - expressionIndex];
            selectParts[0] = SelectClause;
            for (int i = 0; i < selectParts.Length - 1; i++, expressionIndex++)
            {
                selectParts[i + 1] = converter.ConvertToCode(expression.Arguments[expressionIndex]);
            }

            var select = LineSpace(selectParts);

            //select elemnts.
            var selectTargets = expression.Arguments[expression.Arguments.Count - 1];

            //*
            if (typeof(IAsterisk).IsAssignableFromEx(selectTargets.Type))
            {
                select.Add("*".ToCode());
                return new SelectClauseCode(select);
            }

            //new []{ a, b, c} recursive.
            else if (selectTargets.Type.IsArray)
            {
                var newArrayExp = selectTargets as NewArrayExpression;

                var array = new ICode[newArrayExp.Expressions.Count];
                for (int i = 0; i < array.Length; i++)
                {
                    array[i] = converter.ConvertToCode(newArrayExp.Expressions[i]);
                }

                var coreCode = new VCode(select, new VCode(array) { Indent = 1, Separator = "," });
                return new SelectClauseCode(coreCode);
            }

            //new { item = db.tbl.column }
            else
            {
                var createInfo = ObjectCreateAnalyzer.MakeSelectInfo(selectTargets);
                var elements = new ICode[createInfo.Members.Length];
                for (int i = 0; i < elements.Length; i++)
                {
                    elements[i] = ConvertSelectedElement(converter, createInfo.Members[i]);
                }

                var coreCode = new VCode(select, new VCode(elements) { Indent = 1, Separator = "," });
                return new SelectClauseCode(coreCode);
            }
        }
        internal IEnumerable<ICode> InitAndConvertArguments(MethodCallExpression expression, ExpressionConverter converter)
        {
            lock (this)
            {
                if (string.IsNullOrEmpty(Name)) Name = expression.Method.Name.ToUpper();

                if (NameCode == null) NameCode = Name.ToCode();

                if (_startIndex == -1) _startIndex = expression.SkipMethodChain(0);

                if (_isParamArray == null)
                {
                    var paramsInfo = expression.Method.GetParameters();
                    _isParamArray = new bool[paramsInfo.Length];
                    for (int i = 0; i < paramsInfo.Length; i++)
                    {
                        _isParamArray[i] = paramsInfo[i].GetAttribute<ParamArrayAttribute>() != null;
                    }
                }
            }

            var args = new List<ICode>();
            for (int i = _startIndex; i < expression.Arguments.Count; i++)
            {
                var argExp = expression.Arguments[i];
                if (_isParamArray[i])
                {
                    var newArrayExp = argExp as NewArrayExpression;
                    if (newArrayExp != null)
                    {
                        foreach (var e in newArrayExp.Expressions) args.Add(converter.ConvertToCode(e));
                    }
                    else
                    {
                        var obj = converter.ConvertToObject(argExp);
                        foreach (var e in (IEnumerable)obj) args.Add(converter.ConvertToCode(e));
                    }
                }
                else
                {
                    args.Add(converter.ConvertToCode(argExp));
                }
            }
            return args;
        }
 /// <summary>
 /// Convert expression to code.
 /// </summary>
 /// <param name="expression">Expression.</param>
 /// <param name="converter">Expression converter.</param>
 /// <returns>Parts.</returns>
 public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter)
 {
     var condition = converter.ConvertToCode(expression.Arguments[expression.SkipMethodChain(0)]);
     if (condition.IsEmpty) return string.Empty.ToCode();
     return Clause(_nameCode, condition);
 }