Exemple #1
0
        private void BuildSingleField(string methodName, string prefix, ITableRegions regions)
        {
            IEnumerable <KeyValuePair <string, string> > names = regions.ReadOrWrites;

            if (buildCast)
            {
                names = names.Where(kv => InCastList(kv.Key));
            }

            if (names.Count() == 0)
            {
                throw new DException("未指定查询字段!");
            }

            names.ForEach((kv, index) =>
            {
                if (index > 0)
                {
                    SQLWriter.Delimiter();
                }

                SQLWriter.Write(methodName);
                SQLWriter.OpenBrace();

                SQLWriter.Name(prefix, kv.Value);

                SQLWriter.CloseBrace();
                SQLWriter.As(kv.Key);
            });
        }
        // used by
        // X:\jsc.svn\core\ScriptCoreLib.Async\ScriptCoreLib.Async\Query\Experimental\QueryExpressionBuilderAsync.SumAsync.cs
        // return DbCommand to provide Async versions of execute.
        public static DbCommand GetScalarCommand <TElement>(
            this IQueryStrategy <TElement> source,
            IDbConnection cc,

            MethodInfo Operand
            )
        {
            //Console.WriteLine("enter GetScalarCommand " + new { cc });

            var nsource = new xScalar {
                source = source, Operand = Operand
            };
            var Command = default(DbCommand);


            if (cc != null)
            {
                Command = (DbCommand)cc.CreateCommand();
            }
            else
            {
                // X:\jsc.svn\examples\javascript\LINQ\test\auto\TestSelect\TestAndroidInsert\ApplicationWebService.cs

                Console.WriteLine("enter GetScalarCommand cc null ?");
            }

            var w = new SQLWriter <TElement>(nsource, new IQueryStrategy[] { nsource }, Command: Command);

            return(Command);
        }
Exemple #3
0
        private Expression JoinMethod(MethodCallExpression node)
        {
            WriteAppendAtFix(() =>
            {
                buildJoin = true;

                buildFrom = true;

                base.Visit(node.Arguments[0]);

                buildFrom = true;

                base.Visit(node.Arguments[1]);

                buildFrom = false;
            }, () =>
            {
                SQLWriter.Write(" ON ");

                buildFrom = false;

                base.Visit(node.Arguments[2]);

                SQLWriter.Equal();

                base.Visit(node.Arguments[3]);
            });

            return(node);
        }
Exemple #4
0
        protected override MemberAssignment VisitMemberAssignment(MemberAssignment node)
        {
            var me = base.VisitMemberAssignment(node);

            SQLWriter.As(node.Member.Name);

            return(me);
        }
Exemple #5
0
        private void BuildColumns(ITableRegions regions)
        {
            string prefix = GetOrAddTablePrefix(regions.TableType);

            if (buildExists && regions.ReadOrWrites.Count > 0)
            {
                regions.ReadOrWrites.ForEach((kv, index) =>
                {
                    if (index > 0)
                    {
                        SQLWriter.Delimiter();
                    }

                    SQLWriter.Name(prefix, kv.Value);

                    if (kv.Key.ToLower() != kv.Value.ToLower())
                    {
                        SQLWriter.As(kv.Key);
                    }
                });
                return;
            }

            IEnumerable <KeyValuePair <string, string> > names = regions.ReadOrWrites;

            if (buildCast)
            {
                names = names.Where(x => InCastList(x.Key));
            }

            if (names.Count() == 0)
            {
                throw new DException("未指定查询字段!");
            }

            names.ForEach((kv, index) =>
            {
                if (index > 0)
                {
                    SQLWriter.Delimiter();
                }

                SQLWriter.Name(prefix, kv.Value);

                if (kv.Key.ToLower() != kv.Value.ToLower())
                {
                    SQLWriter.As(kv.Key);
                }
            });
        }
Exemple #6
0
        protected override MemberAssignment VisitMemberAssignment(MemberAssignment node)
        {
            var regions = MakeTableRegions(typeof(T));

            if (regions.ReadWrites.TryGetValue(node.Member.Name, out string value))
            {
                SQLWriter.Name(value);
                SQLWriter.Write("=");

                return(base.VisitMemberAssignment(node));
            }

            throw new ExpressionNotSupportedException($"{node.Member.Name}字段不可写!");
        }
Exemple #7
0
        private Expression SingleFieldMethod(MethodCallExpression node)
        {
            string name = node.Method.Name;

            if (name == MethodCall.Average)
            {
                name = "Avg";
            }
            else if (name == MethodCall.LongCount)
            {
                name = MethodCall.Count;
            }

            isAggregation = true;

            if (node.Arguments.Count > 1 || !(isNoParameterCount = name == MethodCall.Count))
            {
                _MethodLevel += 1;
            }

            if (buildSelect)
            {
                buildSelect = false;

                if (node.Arguments.Count > 1 || name == MethodCall.Count)
                {
                    return(SingleFieldTwoArgOrCountMethod(name, node));
                }

                return(SingleFieldOnlyArgMethod(name, node.Arguments[0]));
            }

            if (node.Arguments.Count > 1 || name == MethodCall.Count)
            {
                SQLWriter.Write(name);
                SQLWriter.OpenBrace();
                if (node.Arguments.Count > 1)
                {
                    base.Visit(node.Arguments[1]);
                }
                else
                {
                    SQLWriter.Write("1");
                }
                SQLWriter.CloseBrace();
                return(node);
            }

            return(BuildSingleOneArgField(name, node));
        }
Exemple #8
0
        public static DbCommand GetSelectCommand <TElement>(this IQueryStrategy <TElement> source, IDbConnection cc)
        {
            // X:\jsc.svn\examples\javascript\LINQ\test\auto\TestSelect\TestSelectXElement\Program.cs

            var c = default(DbCommand);

            if (cc != null)
            {
                c = (DbCommand)cc.CreateCommand();
            }

            var w = new SQLWriter <TElement>(source, new IQueryStrategy[0].AsEnumerable(), Command: c);

            return(c);
        }
        public static void Delete <TElement>(this IEnumerable <TElement> source)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/20140705/20140705


            // how was it done before?
            // tested by?

            var nsource = new xDelete {
                source = source
            };


            var c = new object();


            var w = new SQLWriter <TElement>(nsource, new IEnumerable[] { nsource }, Command: c);
        }
Exemple #10
0
        public static DataTable AsDataTable <TElement>(this IQueryStrategy <TElement> source, IDbConnection cc)
        {
            // X:\jsc.svn\examples\javascript\LINQ\test\auto\TestSelect\TestSelectMath\Program.cs

            var c = (DbCommand)cc.CreateCommand();

            var w = new SQLWriter <TElement>(source, new IQueryStrategy[0].AsEnumerable(), Command: c);


            var a = new __DbDataAdapter {
                SelectCommand = c
            };

            var t = new DataTable();

            a.Fill(t);

            return(t);
        }
Exemple #11
0
        private Expression VisitMethodAll(MethodCallExpression node)
        {
            if (node.Method.DeclaringType == typeof(Queryable))
            {
                VisitExists(node);

                SQLWriter.WriteAnd();

                return(WrapNot(() =>
                {
                    _fromSwitch.UnWrap(() => _whereSwitch.UnWrap(() => _orderBySwitch.UnWrap(() =>
                    {
                        VisitExists(node, true);
                    })));

                    return node;
                }));
            }
            throw new ExpressionNotSupportedException($"仅支持“System.Linq.Queryable”中的{node.Method.Name}函数!");
        }
Exemple #12
0
        private Expression SingleFieldOnlyArgMethod(string name, Expression node)
        {
            WriteAppendAtFix(() =>
            {
                SQLWriter.Select();

                BuildSingleOneArgField(name, node);

                if (SQLWriter.IsUnion)
                {
                    _fromSwitch.Execute();
                    SQLWriter.OpenBrace();
                    SQLWriter.AppendAt = -1;
                    SQLWriter.CloseBrace();
                    SQLWriter.WhiteSpace();
                    SQLWriter.TableName("CTE_UNION");
                }
            }, () => base.Visit(node));

            return(node);
        }
        public static void Delete <TElement>(this IQueryStrategy <TElement> source, IDbConnection cc)
        {
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/20140705/20140705


            // how was it done before?
            // tested by?

            var nsource = new xDelete {
                source = source
            };


            var c = (DbCommand)cc.CreateCommand();


            var w = new SQLWriter <TElement>(nsource, new IQueryStrategy[] { nsource }, Command: c);


            // Additional information: There is already an open DataReader associated with this Connection which must be closed first.
            c.ExecuteNonQuery();
        }
Exemple #14
0
        private void MakeSelectFrom(Type type)
        {
            var regions = MakeTableRegions(type);

            if (buildSelect)
            {
                buildSelect = false;

                SQLWriter.Select();

                if (isDistinct)
                {
                    SQLWriter.Distinct();
                }

                BuildColumns(regions);
            }

            if (buildFrom)
            {
                MakeFrom(regions);
            }
        }
Exemple #15
0
        private Expression SingleFieldTwoArgOrCountMethod(string name, MethodCallExpression node)
        {
            WriteAppendAtFix(() =>
            {
                SQLWriter.Select();

                SQLWriter.Write(name);
                SQLWriter.OpenBrace();

                if (node.Arguments.Count > 1)
                {
                    base.Visit(node.Arguments[1]);
                }
                else
                {
                    SQLWriter.Write("1");
                }

                SQLWriter.CloseBrace();

                if (SQLWriter.IsUnion)
                {
                    SQLWriter.From();
                    SQLWriter.OpenBrace();
                }
            }, () => base.Visit(node.Arguments[0]));

            if (SQLWriter.IsUnion)
            {
                SQLWriter.CloseBrace();
                SQLWriter.WhiteSpace();

                SQLWriter.TableName("CTE_UNION");
            }

            return(node);
        }
Exemple #16
0
        public static List <string> BuildSQL(EmoteTable emoteTable)
        {
            emoteTable.NormalRange();

            return(SQLWriter.GetSQL(emoteTable));
        }
Exemple #17
0
        private Expression VisitExecuteMethodCall(MethodCallExpression node)
        {
            switch (node.Method.Name)
            {
            case MethodCall.From:

                var value = (Func <ITableRegions, string>)node.Arguments[1].GetValueFromExpression();

                if (value == null)
                {
                    throw new DException("指定表名称不能为空!");
                }

                SetTableFactory(value);

                base.Visit(node.Arguments[0]);

                return(node);

            case MethodCall.Where:
                if (Behavior == ExecuteBehavior.Insert)
                {
                    throw new ExpressionNotSupportedException("插入语句不支持条件,请在查询器中使用条件过滤!");
                }

                return(MakeWhereNode(node));

            case MethodCall.Update:
                Behavior = ExecuteBehavior.Update;

                base.Visit(node.Arguments[0]);

                SQLWriter.AppendAt = 0;

                SQLWriter.Update();

                SQLWriter.Alias(GetOrAddTablePrefix(typeof(T)));

                SQLWriter.Set();

                base.Visit(node.Arguments[1]);

                SQLWriter.From();

                WriteTable(typeof(T));

                SQLWriter.AppendAt = -1;

                return(node);

            case MethodCall.Delete:
                Behavior = ExecuteBehavior.Delete;

                base.Visit(node.Arguments[0]);

                SQLWriter.AppendAt = 0;

                SQLWriter.Delete();

                SQLWriter.Alias(GetOrAddTablePrefix(typeof(T)));

                SQLWriter.From();

                WriteTable(typeof(T));

                SQLWriter.AppendAt = -1;

                return(node);

            case MethodCall.Insert:
                Behavior = ExecuteBehavior.Insert;

                base.Visit(node.Arguments[0]);

                SQLWriter.AppendAt = 0;
                SQLWriter.Insert();

                WriteTable(typeof(T));

                SQLWriter.AppendAt = -1;

                VisitBuilder(node.Arguments[1]);

                return(node);
            }

            throw new ExpressionNotSupportedException();
        }
Exemple #18
0
        /// <summary>
        /// Queryable 拓展方法
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        protected virtual Expression VisitQueryableExtentionsMethodCall(MethodCallExpression node)
        {
            string name = node.Method.Name;

            switch (name)
            {
            case MethodCall.From:

                var value = (Func <ITableRegions, string>)node.Arguments[1].GetValueFromExpression();

                if (value == null)
                {
                    throw new DException("指定表名称不能为空!");
                }

                if (!buildFrom)
                {
                    base.Visit(node.Arguments[0]);
                }

                SetTableFactory(value);

                if (buildFrom)
                {
                    return(base.Visit(node.Arguments[0]));
                }

                return(node);

            case MethodCall.TakeFirst:
            case MethodCall.TakeFirstOrDefault:
            case MethodCall.TakeSingle:
            case MethodCall.TakeSingleOrDefault:

                // TOP(1)
                SQLWriter.Take = 1;

                buildSelect = false;

                SQLWriter.Select();

                buildFrom = false;

                WriteAppendAtFix(() =>
                {
                    if (isDistinct)
                    {
                        SQLWriter.Distinct();
                    }

                    buildFrom = true;
                    base.Visit(node.Arguments[1]);
                    buildFrom = false;
                }, () => base.Visit(node.Arguments[0]));

                return(node);

            case MethodCall.TakeLast:
            case MethodCall.TakeLastOrDefault:

                // TOP(..)
                SQLWriter.Take = 1;

                isOrderByReverse ^= true;

                buildSelect = false;

                SQLWriter.Select();

                buildFrom = false;

                WriteAppendAtFix(() =>
                {
                    if (isDistinct)
                    {
                        SQLWriter.Distinct();
                    }

                    buildFrom = true;
                    base.Visit(node.Arguments[1]);
                    buildFrom = false;
                }, () => base.Visit(node.Arguments[0]));

                if (!isContainsOrderBy)
                {
                    throw new ExpressionNotSupportedException($"使用函数({name})时,必须使用排序函数(OrderBy/OrderByDescending)!");
                }

                return(node);

            default:
                return(VisitFormatterMethodCall(node));
            }
        }
Exemple #19
0
        private Expression VisitExists(MethodCallExpression node, bool isNotWrap = false)
        {
            SQLWriter.Exists();

            SQLWriter.OpenBrace();

            bool join = buildJoin;

            buildJoin   = false;
            buildSelect = buildFrom = true;

            if (isNotWrap || node.Arguments.Count == 1)
            {
                UnWrap(() =>
                {
                    buildExists = true;

                    base.Visit(node.Arguments[0]);

                    buildExists = false;

                    if (node.Arguments.Count > 1)
                    {
                        _whereSwitch.Execute();

                        WrapNot(() =>
                        {
                            base.Visit(node.Arguments[1]);
                        });
                    }
                });
            }
            else
            {
                UnWrap(() =>
                {
                    int length = 0;

                    WriteAppendAtFix(() =>
                    {
                        buildExists = true;

                        base.Visit(node.Arguments[0]);

                        buildExists = false;
                    }, () =>
                    {
                        base.Visit(node.Arguments[1]);

                        length = SQLWriter.Length;
                    }, index =>
                    {
                        SQLWriter.AppendAt = SQLWriter.Length - (length - index);

                        _whereSwitch.Execute();
                    });
                });
            }

            SQLWriter.CloseBrace();

            buildJoin = join;

            return(node);
        }
Exemple #20
0
        /// <summary>
        ///  System.Linq.Queryable 的函数
        /// </summary>
        /// <param name="node">表达式</param>
        /// <returns></returns>
        protected virtual Expression VisitQueryableMethodCall(MethodCallExpression node)
        {
            //? 函数名称
            string name = node.Method.Name;

            if (node.Arguments.Count > 1 ?
                !(name == MethodCall.Take || name == MethodCall.Skip || name == MethodCall.TakeLast || name == MethodCall.SkipLast) :
                (name == MethodCall.Sum || name == MethodCall.Max || name == MethodCall.Min || name == MethodCall.Average)
                )
            {
                _MethodLevel += 1;
            }

            switch (name)
            {
            case MethodCall.Any:

                if (Parent?.BuildWhere ?? BuildWhere)
                {
                    return(VisitExists(node));
                }

                if (buildSelect)
                {
                    SQLWriter.Select();
                }

                SQLWriter.Write("CASE WHEN ");

                VisitExists(node);

                SQLWriter.Write(" THEN ");
                SQLWriter.Parameter("__variable_true", true);
                SQLWriter.Write(" ELSE ");
                SQLWriter.Parameter("__variable_false", false);
                SQLWriter.Write(" END");

                return(node);

            case MethodCall.All:

                if (Parent?.BuildWhere ?? BuildWhere)
                {
                    SQLWriter.OpenBrace();

                    VisitMethodAll(node);

                    SQLWriter.CloseBrace();
                }
                else
                {
                    if (buildSelect)
                    {
                        SQLWriter.Select();
                    }

                    SQLWriter.Write("CASE WHEN ");

                    VisitMethodAll(node);

                    SQLWriter.Write(" THEN ");
                    SQLWriter.Parameter("__variable_true", true);
                    SQLWriter.Write(" ELSE ");
                    SQLWriter.Parameter("__variable_false", false);
                    SQLWriter.Write(" END");
                }
                return(node);

            case MethodCall.ElementAt:
            case MethodCall.ElementAtOrDefault:

                base.Visit(node.Arguments[0]);

                int index = (int)node.Arguments[1].GetValueFromExpression();

                if (index < 0)
                {
                    throw new IndexOutOfRangeException();
                }

                if (SQLWriter.Take > 0 && index < SQLWriter.Take)
                {
                    throw new IndexOutOfRangeException();
                }

                SQLWriter.Take = 1;

                SQLWriter.Skip += index;

                return(node);

            case MethodCall.Take:
            case MethodCall.TakeLast:

                if (isAggregation)
                {
                    throw new ExpressionNotSupportedException($"使用聚合函数时,禁止使用分页函数({name})!");
                }

                if (name == MethodCall.TakeLast)
                {
                    isOrderByReverse ^= true;
                }

                base.Visit(node.Arguments[0]);

                if (!isContainsOrderBy && name == MethodCall.TakeLast)
                {
                    throw new ExpressionNotSupportedException($"使用函数({name})时,必须使用排序函数(OrderBy/OrderByDescending)!");
                }

                int take = (int)node.Arguments[1].GetValueFromExpression();

                if (take < 0)
                {
                    throw new ArgumentOutOfRangeException($"使用{name}函数,参数值不能小于零!");
                }

                if (SQLWriter.Take > 0 && take < SQLWriter.Take)
                {
                    throw new IndexOutOfRangeException();
                }

                if (SQLWriter.Take == 0)
                {
                    SQLWriter.Take = take;
                }

                return(node);

            case MethodCall.Single:
            case MethodCall.SingleOrDefault:
            case MethodCall.First:
            case MethodCall.FirstOrDefault:

                // TOP(1)
                SQLWriter.Take = 1;

                if (node.Arguments.Count > 1)
                {
                    MakeWhere(node);
                }
                else
                {
                    base.Visit(node.Arguments[0]);
                }

                return(node);

            case MethodCall.Last:
            case MethodCall.LastOrDefault:

                // TOP(..)
                SQLWriter.Take = 1;

                isOrderByReverse ^= true;

                if (node.Arguments.Count > 1)
                {
                    MakeWhere(node);
                }
                else
                {
                    base.Visit(node.Arguments[0]);
                }

                if (!isContainsOrderBy)
                {
                    throw new ExpressionNotSupportedException($"使用函数({name})时,必须使用排序函数(OrderBy/OrderByDescending)!");
                }

                return(node);

            case MethodCall.Skip:
            case MethodCall.SkipLast:

                if (isAggregation)
                {
                    throw new ExpressionNotSupportedException($"使用聚合函数时,禁止使用分页函数({name})!");
                }

                if (name == MethodCall.SkipLast)
                {
                    isOrderByReverse ^= true;
                }

                base.Visit(node.Arguments[0]);

                if (!isContainsOrderBy && name == MethodCall.SkipLast)
                {
                    throw new ExpressionNotSupportedException($"使用函数({name})时,必须使用排序函数(OrderBy/OrderByDescending)!");
                }

                int skip = (int)node.Arguments[1].GetValueFromExpression();

                if (skip < 0)
                {
                    throw new ArgumentOutOfRangeException($"使用({name})函数,参数值不能小于零!");
                }

                SQLWriter.Skip += skip;

                return(node);

            case MethodCall.Distinct:

                isDistinct = true;

                return(base.Visit(node.Arguments[0]));

            case MethodCall.Reverse:

                isOrderByReverse ^= true;

                base.Visit(node.Arguments[0]);

                if (!isContainsOrderBy)
                {
                    throw new ExpressionNotSupportedException($"使用函数({name})时,必须使用排序函数(OrderBy/OrderByDescending)!");
                }

                return(node);

            case MethodCall.OrderBy:
            case MethodCall.ThenBy:
            case MethodCall.OrderByDescending:
            case MethodCall.ThenByDescending:

                isContainsOrderBy = true;

                base.Visit(node.Arguments[0]);

                if (isAggregation)
                {
                    return(node);
                }

                SQLWriter.IsOrderBy = true;

                _orderBySwitch.Execute();

                base.Visit(node.Arguments[1]);

                if (isOrderByReverse ^ name.EndsWith("Descending"))
                {
                    SQLWriter.WriteDesc();
                }
                SQLWriter.IsOrderBy = false;
                return(node);

            case MethodCall.Where:
            case MethodCall.TakeWhile:
                return(MakeWhere(node));

            case MethodCall.SkipWhile:
                return(WrapNot(() =>
                {
                    return MakeWhere(node);
                }));

            case MethodCall.Select:

                if (_MethodLevel > 1)
                {
                    throw new ExpressionNotSupportedException($"请将函数({name})置于查询最后一个包含入参的函数之后!");
                }

                if (isNoParameterCount)
                {
                    return(base.Visit(node.Arguments[0]));
                }

                buildSelect = false;

                SQLWriter.Select();

                buildFrom = false;

                WriteAppendAtFix(() =>
                {
                    if (isDistinct)
                    {
                        SQLWriter.Distinct();
                    }

                    buildFrom = true;
                    base.Visit(node.Arguments[1]);
                    buildFrom = false;
                }, () => base.Visit(node.Arguments[0]));

                return(node);

            case MethodCall.Max:
            case MethodCall.Min:
            case MethodCall.Sum:
            case MethodCall.Count:
            case MethodCall.Average:
            case MethodCall.LongCount:
                return(SingleFieldMethod(node));

            case MethodCall.Join:
                return(JoinMethod(node));

            case MethodCall.Union:
            case MethodCall.Concat:
            case MethodCall.Intersect:

                buildSelect = false;

                SQLWriter.IsUnion = false;

                VisitBuilder(node.Arguments[0]);

                if (name == MethodCall.Intersect)
                {
                    SQLWriter.Write(" INTERSECT ");
                }
                else
                {
                    SQLWriter.Write(MethodCall.Union == name ? " UNION " : " UNION ALL ");
                }

                VisitBuilder(node.Arguments[1]);

                SQLWriter.IsUnion = true;

                return(node);

            case MethodCall.Cast:

                Type type = node.Type.GetGenericArguments().First();

                if (type.IsValueType || type == typeof(string) || typeof(IEnumerable).IsAssignableFrom(type))
                {
                    throw new TypeAccessInvalidException($"{name}函数泛型参数类型不能是值类型、字符串类型或迭代类型!");
                }

                var castToType = node.Arguments
                                 .Select(x => x.Type)
                                 .First();

                if (node.Type == castToType)
                {
                    return(base.Visit(node.Arguments[0]));
                }

                useCast = true;

                _TypeCache.GetOrAdd(type, _ => GetInitialType(castToType));

                if (!buildSelect)
                {
                    return(base.Visit(node.Arguments[0]));   //? 说明Cast函数在Select函数之前,不需要进行函数分析!
                }
                var entry = RuntimeTypeCache.Instance.GetCache(type);

                if (_CastList is null)
                {
                    _CastList = entry.PropertyStores
                                .Select(x => x.Name.ToLower())
                                .ToList();
                }
                else     //? 取交集
                {
                    _CastList = _CastList
                                .Intersect(entry.PropertyStores.Select(x => x.Name.ToLower()))
                                .ToList();
                }

                if (_CastList.Count == 0)
                {
                    throw new DException("未指定查询字段!");
                }

                buildCast = true;

                return(base.Visit(node.Arguments[0]));

            default:
                return(VisitFormatterMethodCall(node));
            }
        }