public override string ExpressionLambdaToSqlMemberAccessDateTime(MemberExpression exp, ExpTSC tsc)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Now": return(_common.Now);

                case "UtcNow": return(_common.NowUtc);

                case "Today": return("date");

                case "MinValue": return("'1753/1/1 0:00:00'");

                case "MaxValue": return("'9999/12/31 23:59:59'");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, tsc);

            switch (exp.Member.Name)
            {
            case "Date": return($"format({left},'yyyy-mm-dd')");

            case "TimeOfDay": return($"datediff('s', format({left},'yyyy-mm-dd'), {left})");

            case "DayOfWeek": return($"(format({left},'w')-1)");

            case "Day": return($"day({left})");

            case "DayOfYear": return($"format({left},'y')");

            case "Month": return($"month({left})");

            case "Year": return($"year({left})");

            case "Hour": return($"hour({left})");

            case "Minute": return($"minute({left})");

            case "Second": return($"second({left})");

            case "Millisecond": return($"(second({left})/1000)");

            case "Ticks": return($"({MsAccessUtils.GetCastSql($"datediff('s', '1970-1-1', {left})", typeof(long))}*10000000+621355968000000000)");
            }
            return(null);
        }
Exemple #2
0
        public override string StringConcat(string[] objs, Type[] types)
        {
            var sb   = new StringBuilder();
            var news = new string[objs.Length];

            for (var a = 0; a < objs.Length; a++)
            {
                if (types[a] == typeof(string))
                {
                    news[a] = objs[a];
                }
                else
                {
                    news[a] = MsAccessUtils.GetCastSql(objs[a], typeof(string));
                }
            }
            return(string.Join(" + ", news));
        }
        public override string ExpressionLambdaToSqlMemberAccessTimeSpan(MemberExpression exp, ExpTSC tsc)
        {
            if (exp.Expression == null)
            {
                switch (exp.Member.Name)
                {
                case "Zero": return("0");

                case "MinValue": return("-922337203685477580");    //微秒 Ticks / 10

                case "MaxValue": return("922337203685477580");
                }
                return(null);
            }
            var left = ExpressionLambdaToSql(exp.Expression, tsc);

            switch (exp.Member.Name)
            {
            case "Days": return($"clng(({left})/{60 * 60 * 24}+1)");

            case "Hours": return($"clng(({left})/{60 * 60} mod 24+1)");

            case "Milliseconds": return($"({MsAccessUtils.GetCastSql(left, typeof(long))}*1000)");

            case "Minutes": return($"clng(({left})/60 mod 60+1)");

            case "Seconds": return($"(({left}) mod 60)");

            case "Ticks": return($"({MsAccessUtils.GetCastSql(left, typeof(long))}*10000000)");

            case "TotalDays": return($"(({left})/{60 * 60 * 24})");

            case "TotalHours": return($"(({left})/{60 * 60})");

            case "TotalMilliseconds": return($"({MsAccessUtils.GetCastSql(left, typeof(long))}*1000)");

            case "TotalMinutes": return($"(({left})/60)");

            case "TotalSeconds": return($"({left})");
            }
            return(null);
        }
        public override string ExpressionLambdaToSqlOther(Expression exp, ExpTSC tsc)
        {
            Func <Expression, string> getExp = exparg => ExpressionLambdaToSql(exparg, tsc);

            switch (exp.NodeType)
            {
            //case ExpressionType.ArrayLength:
            //    var arrOper = (exp as UnaryExpression)?.Operand;
            //    if (arrOper.Type == typeof(byte[])) return $"lenb({getExp(arrOper)})";  #505
            //    break;
            case ExpressionType.Convert:
                var operandExp = (exp as UnaryExpression)?.Operand;
                var gentype    = exp.Type.NullableTypeOrThis();
                if (gentype != operandExp.Type.NullableTypeOrThis())
                {
                    var retBefore = getExp(operandExp);
                    var retAfter  = MsAccessUtils.GetCastSql(retBefore, gentype);
                    if (retBefore != retAfter)
                    {
                        return(retAfter);
                    }
                }
                break;

            case ExpressionType.Call:
                var callExp = exp as MethodCallExpression;

                switch (callExp.Method.Name)
                {
                case "Parse":
                case "TryParse":
                    var retBefore = getExp(callExp.Arguments[0]);
                    var retAfter  = MsAccessUtils.GetCastSql(retBefore, callExp.Method.DeclaringType.NullableTypeOrThis());
                    if (retBefore != retAfter)
                    {
                        return(retAfter);
                    }
                    return(null);

                case "NewGuid":
                    switch (callExp.Method.DeclaringType.NullableTypeOrThis().ToString())
                    {
                    case "System.Guid": return($"newid()");
                    }
                    return(null);

                case "Next":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("rnd*1000000000000000");
                    }
                    return(null);

                case "NextDouble":
                    if (callExp.Object?.Type == typeof(Random))
                    {
                        return("rnd");
                    }
                    return(null);

                case "Random":
                    if (callExp.Method.DeclaringType.IsNumberType())
                    {
                        return("rnd");
                    }
                    return(null);

                case "ToString":
                    if (callExp.Object != null)
                    {
                        return(callExp.Arguments.Count == 0 ? MsAccessUtils.GetCastSql(getExp(callExp.Object), typeof(string)) : null);
                    }
                    return(null);
                }

                var objExp  = callExp.Object;
                var objType = objExp?.Type;
                if (objType?.FullName == "System.Byte[]")
                {
                    return(null);
                }

                var argIndex = 0;
                if (objType == null && callExp.Method.DeclaringType == typeof(Enumerable))
                {
                    objExp  = callExp.Arguments.FirstOrDefault();
                    objType = objExp?.Type;
                    argIndex++;

                    if (objType == typeof(string))
                    {
                        switch (callExp.Method.Name)
                        {
                        case "First":
                        case "FirstOrDefault":
                            return($"left({getExp(callExp.Arguments[0])}, 1)");
                        }
                    }
                }
                if (objType == null)
                {
                    objType = callExp.Method.DeclaringType;
                }
                if (objType != null || objType.IsArrayOrList())
                {
                    if (argIndex >= callExp.Arguments.Count)
                    {
                        break;
                    }
                    tsc.SetMapColumnTmp(null);
                    var args1       = getExp(callExp.Arguments[argIndex]);
                    var oldMapType  = tsc.SetMapTypeReturnOld(tsc.mapTypeTmp);
                    var oldDbParams = tsc.SetDbParamsReturnOld(null);
                    var left        = objExp == null ? null : getExp(objExp);
                    tsc.SetMapColumnTmp(null).SetMapTypeReturnOld(oldMapType);
                    tsc.SetDbParamsReturnOld(oldDbParams);
                    switch (callExp.Method.Name)
                    {
                    case "Contains":
                        //判断 in //在各大 Provider AdoProvider 中已约定,500元素分割, 3空格\r\n4空格
                        return($"(({args1}) in {left.Replace(",   \r\n    \r\n", $") \r\n OR ({args1}) in (")})");
                    }
                }
                break;

            case ExpressionType.NewArrayInit:
                var arrExp = exp as NewArrayExpression;
                var arrSb  = new StringBuilder();
                arrSb.Append("(");
                for (var a = 0; a < arrExp.Expressions.Count; a++)
                {
                    if (a > 0)
                    {
                        arrSb.Append(",");
                    }
                    if (a % 500 == 499)
                    {
                        arrSb.Append("   \r\n    \r\n");                     //500元素分割, 3空格\r\n4空格
                    }
                    arrSb.Append(getExp(arrExp.Expressions[a]));
                }
                if (arrSb.Length == 1)
                {
                    arrSb.Append("NULL");
                }
                return(arrSb.Append(")").ToString());

            case ExpressionType.ListInit:
                var listExp = exp as ListInitExpression;
                var listSb  = new StringBuilder();
                listSb.Append("(");
                for (var a = 0; a < listExp.Initializers.Count; a++)
                {
                    if (listExp.Initializers[a].Arguments.Any() == false)
                    {
                        continue;
                    }
                    if (a > 0)
                    {
                        listSb.Append(",");
                    }
                    listSb.Append(getExp(listExp.Initializers[a].Arguments.FirstOrDefault()));
                }
                if (listSb.Length == 1)
                {
                    listSb.Append("NULL");
                }
                return(listSb.Append(")").ToString());

            case ExpressionType.New:
                var newExp = exp as NewExpression;
                if (typeof(IList).IsAssignableFrom(newExp.Type))
                {
                    if (newExp.Arguments.Count == 0)
                    {
                        return("(NULL)");
                    }
                    if (typeof(IEnumerable).IsAssignableFrom(newExp.Arguments[0].Type) == false)
                    {
                        return("(NULL)");
                    }
                    return(getExp(newExp.Arguments[0]));
                }
                return(null);
            }
            return(null);
        }