<commit_before>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using ToolGood.ReadyGo3.LinQ.Expressions;
using ToolGood.ReadyGo3.PetaPoco.Core;

namespace ToolGood.ReadyGo3.LinQ
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    public partial class WhereHelper<T1>
        where T1 : class, new()
    {
        internal WhereHelper(SqlHelper helper)
        {
            this._sqlhelper = helper;
            this._paramPrefix = DatabaseProvider.Resolve(_sqlhelper._sqlType).GetParameterPrefix(_sqlhelper._connectionString);
            _sqlExpression = new Expressions.SqlExpression(_sqlhelper._sqlType);
        }
        #region  01 私有变量
        private SqlExpression _sqlExpression;
        private readonly SqlHelper _sqlhelper;
        private List<object> _args = new List<object>();
        private StringBuilder _where = new StringBuilder();
        private string _joinOnString = "";
        private List<SelectHeader> _includeColumns = new List<SelectHeader>();
        private List<string> _excludeColumns = new List<string>();
        private readonly string _paramPrefix;

        private string _order = "";
        private string _groupby = "";
        private string _having = "";
        private bool _useDistinct = false;
        #endregion

        #region 02 SQL拼接 基础方法

        private bool _doNext = true;

        private bool jump()
        {
            if (_doNext == false) {
                _doNext = true;
                return true;
            }
            return false;
        }

        private void ifTrue(bool iftrue)
        {
            _doNext = iftrue;
        }

        private void whereNotIn(LambdaExpression field, ICollection args)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(field);
            whereNotIn(column, args);
        }

        private void whereNotIn(string column, ICollection args)
        {
            if (jump()) return;

            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            if (args.Count == 0) {
                _where.Append("1=1");
                return;
            }
            _where.Append(column);
            if (args.Count == 1) {
                _where.Append(" <> ");
                _where.Append(_paramPrefix);
                _where.Append(_args.Count.ToString());
            } else {
                _where.Append(" NOT IN (");
                for (int i = 0; i < args.Count; i++) {
                    if (i > 0) {
                        _where.Append(",");
                    }
                    _where.Append(_paramPrefix);
                    _where.Append((_args.Count + i).ToString());
                }
                _where.Append(")");
            }
            foreach (var item in args) {
                _args.Add(item);
            }
        }

        private void whereIn(LambdaExpression field, ICollection args)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(field);
            whereIn(column, args);
        }

        private void whereIn(string column, ICollection args)
        {
            if (jump()) return;

            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            if (args.Count == 0) {
                _where.Append("1=2");
                return;
            }
            _where.Append(column);
            if (args.Count == 1) {
                _where.Append(" = ");
                _where.Append(_paramPrefix);
                _where.Append(_args.Count.ToString());
            } else {
                _where.Append(" IN (");
                for (int i = 0; i < args.Count; i++) {
                    if (i > 0) {
                        _where.Append(",");
                    }
                    _where.Append(_paramPrefix);
                    _where.Append((_args.Count + i).ToString());
                }
                _where.Append(")");
            }
            foreach (var item in args) {
                _args.Add(item);
            }
        }


        internal void where(string where, ICollection args)
        {
            if (jump()) return;
            where = where.Trim();
            if (_where.Length > 0) _where.Append(" AND ");

            int start = 0;
            if (where.StartsWith("where ", StringComparison.CurrentCultureIgnoreCase)) start = 6;

            bool isInText = false, isStart = false;
            var c = 'a';
            var text = "";

            for (int i = start; i < where.Length; i++) {
                var t = where[i];
                if (isInText) {
                    if (t == c) isInText = false;
                } else if ("\"'`".Contains(t)) {
                    isInText = true;
                    c = t;
                    isStart = false;
                } else if (isStart == false) {
                    if (t == '@') {
                        isStart = true;
                        text = "@";
                        continue;
                    }
                } else if ("@1234567890".Contains(t)) {
                    text += t;
                    continue;
                } else {
                    whereTranslate(_where, text);
                    isStart = false;
                }
                _where.Append(t);
            }
            if (isStart) whereTranslate(_where, text);


            foreach (var item in args) {
                _args.Add(item);
            }
        }
        private void whereTranslate(StringBuilder where, string text)
        {
            if (text == "@@") {
                where.Append("@@");
            } else if (text.Length == 1) {
                where.Append(text);
            } else if (text.StartsWith("@")) {
                int p = this._args.Count + int.Parse(text.Replace("@", ""));
                where.Append(_paramPrefix);
                where.Append(p.ToString());
            } else {
                int p = int.Parse(text.Replace("@", ""));
                where.Append(_paramPrefix);
                where.Append(p.ToString());
            }
        }

        private void where(LambdaExpression where)
        {
            if (jump()) return;
            _sqlExpression.Analysis(where, out string sql);
            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            _where.Append(sql);
        }

        private void join(string join)
        {
            if (jump()) return;
            _joinOnString += " " + join;
        }

        private void includeColumn(LambdaExpression column, string asName)
        {
            if (jump()) return;
            var col = _sqlExpression.GetColumnName(column);
            includeColumn(col, asName);
        }
        private void includeColumn(string col, string asName)
        {
            if (jump()) return;
            var index = col.IndexOf('.');
            string table = null;
            if (index > -1) {
                table = col.Substring(0, index);
                col = col.Substring(index + 1);
            }
            if (asName == null) {
                _includeColumns.Insert(0, new SelectHeader() {
                    AsName = col,
                    Table = table,
                    QuerySql = col
                });
            } else {
                _includeColumns.Insert(0, new SelectHeader() {
                    AsName = asName,
                    Table = table,
                    QuerySql = col
                });
            }

        }

        private void excludeColumn(LambdaExpression column)
        {
            if (jump()) return;
            var col = _sqlExpression.GetColumnName(column);
            excludeColumn(col);
        }
        private void excludeColumn(string col)
        {
            if (jump()) return;
            var index = col.IndexOf('.');
            if (index > -1) {
                col = col.Substring(index + 1);
            }
            _excludeColumns.Add(col);
        }


        private void orderBy(LambdaExpression order, OrderType type)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(order);
            if (type == OrderType.Asc) {
                orderBySql(column + " ASC");
            } else {
                orderBySql(column + " DESC");
            }
        }

        private void orderBySql(string order)
        {
            if (jump()) return;
            if (_order.Length > 0) {
                _order += ",";
            }
            _order += order;
        }

        private void groupBy(LambdaExpression group)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(group);
            this.groupBy(column);
        }

        private void groupBy(string groupby)
        {
            if (jump()) return;
            groupby = groupby.Trim().Trim(',');
            if (groupby.StartsWith("group by ", StringComparison.CurrentCultureIgnoreCase))
                groupby = groupby.Substring(9).Trim();
            if (string.IsNullOrWhiteSpace(groupby)) return;
            if (_groupby.Length > 0) {
                _groupby += ",";
            }
            _groupby += groupby;
        }
        private void having(LambdaExpression having)
        {
            if (jump()) return;
            _sqlExpression.Analysis(having, out string sql);
            this.having(sql);
        }
        private void having(string having)
        {
            if (jump()) return;
            having = having.Trim().Trim(',');
            if (having.StartsWith("having ", StringComparison.CurrentCultureIgnoreCase))
                having = having.Substring(7).Trim();

            if (string.IsNullOrWhiteSpace(having)) return;
            if (_having.Length > 0) {
                _having += ",";
            }
            _having += having;
        }
        #endregion SQL拼接方法

        #region 03 判断

        /// <summary>
        /// IfTrue 如果为假会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="ifTrue"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfTrue(bool ifTrue)
        {
            this.ifTrue(ifTrue);
            return this;
        }

        /// <summary>
        /// IfFalse 如果为真会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="ifTrue"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfFalse(bool ifTrue)
        {
            this.ifTrue(ifTrue == false);
            return this;
        }

        /// <summary>
        /// IfSet  如果字符串未设置，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfSet(string txt)
        {
            this.ifTrue(string.IsNullOrEmpty(txt) == false);
            return this;
        }

        /// <summary>
        /// IfNotSet  如果字符串已设置，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotSet(string txt)
        {
            this.ifTrue(string.IsNullOrEmpty(txt));
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(string txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(string txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(short? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(short? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(int? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(int? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(long? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(long? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(ushort? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(ushort? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(uint? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(uint? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(ulong? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(ulong? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(float? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(float? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(double? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(double? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(decimal? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(decimal? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(DateTime? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(DateTime? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        #endregion 判断

        #region 04 Sql 拼接
        /// <summary>
        /// 自动添加 “NOT EXISTS ” 也会自动添加 “SELECT * ”
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotExists(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            where = where.TrimStart();
            if (where.StartsWith("NOT EXISTS ", StringComparison.CurrentCultureIgnoreCase) == false) {
                if (where.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase) == false) {
                    where = $"NOT EXISTS(SELECT * {@where})";
                } else {
                    where = $"NOT EXISTS({@where})";
                }
            }
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 自动添加 “EXISTS ” 也会自动添加 “SELECT * ”
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereExists(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            where = where.TrimStart();
            if (where.StartsWith("EXISTS ", StringComparison.CurrentCultureIgnoreCase) == false) {
                if (where.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase) == false) {
                    where = $"EXISTS(SELECT * {@where})";
                } else {
                    where = $"EXISTS({@where})";
                }
            }
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> Where(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 添加 Order By SQL语句
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public WhereHelper<T1> OrderBy(string order)
        {
            if (string.IsNullOrEmpty(order)) throw new ArgumentNullException("order");
            this.orderBySql(order);
            return this;
        }
        /// <summary>
        /// 添加 Group By SQL语句
        /// </summary>
        /// <param name="groupby"></param>
        /// <returns></returns>
        public WhereHelper<T1> GroupBy(string groupby)
        {
            if (string.IsNullOrEmpty(groupby)) throw new ArgumentNullException("groupby");
            this.groupBy(groupby);
            return this;
        }
        /// <summary>
        /// 添加 Having SQL语句
        /// </summary>
        /// <param name="having"></param>
        /// <returns></returns>
        public WhereHelper<T1> Having(string having)
        {
            if (string.IsNullOrEmpty(having)) throw new ArgumentNullException("having");
            this.having(having);
            return this;
        }
        /// <summary>
        /// 添加 Join On SQL语句
        /// </summary>
        /// <param name="joinWithOn"></param>
        /// <returns></returns>
        public WhereHelper<T1> JoinOn(string joinWithOn)
        {
            if (string.IsNullOrEmpty(joinWithOn)) throw new ArgumentNullException("joinWithOn");
            this.join(joinWithOn);
            return this;
        }

        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn(string field, ICollection args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereNotIn(field, args);
            return this;
        }

        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn(string field, params object[] args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereNotIn(field, args);
            return this;
        }

        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn(string field, ICollection args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereIn(field, args);
            return this;
        }

        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn(string field, params object[] args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereIn(field, args);
            return this;
        }

        #endregion Sql 拼接

        #region 05 Sql拼接 LINQ WhereIn Where OrderBy Having
        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn<T>(Expression<Func<T1, T>> field, ICollection args)
        {
            this.whereNotIn(field, args);
            return this;
        }
        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn<T>(Expression<Func<T1, T>> field, params object[] args)
        {
            return WhereNotIn(field, (ICollection)args);
        }
        /// <summary>
        /// Where  In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn<T>(Expression<Func<T1, T>> field, ICollection args)
        {
            this.whereIn(field, args);
            return this;
        }
        /// <summary>
        /// Where  In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn<T>(Expression<Func<T1, T>> field, params object[] args)
        {
            return WhereIn(field, (ICollection)args);
        }
        /// <summary>
        /// Where
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public WhereHelper<T1> Where(Expression<Func<T1, bool>> where)
        {
            this.where(where);
            return this;
        }
        /// <summary>
        /// OrderBy
        /// </summary>
        /// <param name="order"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public WhereHelper<T1> OrderBy<T>(Expression<Func<T1, T>> order, OrderType type = OrderType.Asc)
        {
            this.orderBy(order, type);
            return this;
        }
        /// <summary>
        /// GroupBy
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public WhereHelper<T1> GroupBy<T>(Expression<Func<T1, T>> group)
        {
            groupBy(group);
            return this;
        }
        /// <summary>
        /// Having
        /// </summary>
        /// <param name="having"></param>
        /// <returns></returns>
        public WhereHelper<T1> Having(Expression<Func<T1, bool>> having)
        {
            this.having(having);
            return this;
        }

        /// <summary>
        /// 非重复
        /// </summary>
        /// <param name="distinct"></param>
        /// <returns></returns>
        public WhereHelper<T1> Distinct(bool distinct = true)
        {
            _useDistinct = distinct;
            return this;
        }

        #endregion WhereIn Where OrderBy Having

        #region 06 查询 Select Page SkipTake Single SingleOrDefault First FirstOrDefault


        #region Select Page SkipTake Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(string selectSql = null)
        {
            return _sqlhelper.Select<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="limit"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(long limit, string selectSql = null)
        {
            return _sqlhelper.Select<T1>(limit, 0, GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(long skip, long take, string selectSql = null)
        {
            return _sqlhelper.Select<T1>(skip, take, GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回Page
        /// </summary>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public Page<T1> Page(long page, long itemsPerPage, string selectSql = null)
        {
            return _sqlhelper.Page<T1>(page, itemsPerPage, GetFullSelectSql(selectSql), _args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 Single(string selectSql = null)
        {
            return _sqlhelper.Single<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 SingleOrDefault(string selectSql = null)
        {
            return _sqlhelper.SingleOrDefault<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 First(string selectSql = null)
        {
            return _sqlhelper.First<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 FirstOrDefault(string selectSql = null)
        {
            return _sqlhelper.FirstOrDefault<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }

        #endregion Select Page SkipTake Single SingleOrDefault First FirstOrDefault

        #region Select Page SkipTake Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="limit"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(long limit, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(limit, GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(long skip, long take, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(skip, take, GetFullSelectSql(sql), _args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T Single<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Single<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T SingleOrDefault<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.SingleOrDefault<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T First<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.First<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T FirstOrDefault<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.FirstOrDefault<T>(GetFullSelectSql(sql), _args.ToArray());
        }

        /// <summary>
        /// 查询 返回Page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public Page<T> Page<T>(long page, long itemsPerPage, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Page<T>(page, itemsPerPage, GetFullSelectSql(sql), _args.ToArray());
        }

        #endregion
        #endregion

        #region 07 查询  Count ExecuteDataTable ExecuteDataSet Select Page Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 获取数量
        /// </summary>
        /// <param name="selectSql"></param>
        /// <param name="distinct"></param>
        /// <returns></returns>
        public int SelectCount(string selectSql = null, bool distinct = false)
        {
            return this._sqlhelper.getDatabase().ExecuteScalar<int>(this.GetCountSql(selectSql, distinct), this._args.ToArray());
        }
        /// <summary>
        /// 执行返回DataTable
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public DataTable ExecuteDataTable(string selectSql = null)
        {
            return this._sqlhelper.ExecuteDataTable(this.GetFullSelectSql(selectSql), this._args.ToArray());
        }
        //#if !NETSTANDARD2_0
        /// <summary>
        /// 执行返回DataSet
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public DataSet ExecuteDataSet(string selectSql = null)
        {
            return this._sqlhelper.ExecuteDataSet(this.GetFullSelectSql(selectSql), this._args.ToArray());
        }
        //#endif
        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="limit"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(long limit, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(limit, 0, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(long skip, long take, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(skip, take, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T Single<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Single<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T SingleOrDefault<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.SingleOrDefault<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T First<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.First<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T FirstOrDefault<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.FirstOrDefault<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回页，page类
        /// </summary>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public Page<T> Page<T>(long page, long itemsPerPage, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Page<T>(page, itemsPerPage, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        private string getSelect<T>(string selectSql)
        {
            if (string.IsNullOrEmpty(selectSql) == false) {
                if (selectSql.StartsWith("Select", StringComparison.CurrentCultureIgnoreCase)) {
                    return selectSql;
                }
                return "SELECT " + selectSql;
            }
            return CreateSelectHeader(typeof(T), this._includeColumns);
        }
        #endregion

        #region 08 包含列 排除列
        /// <summary>
        /// 排除列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="column"></param>
        /// <returns></returns>
        public WhereHelper<T1> RemoveColumn<T>(Expression<Func<T1, T>> column)
        {
            excludeColumn(column);
            return this;
        }
        /// <summary>
        /// 排除列
        /// </summary>
        /// <param name="columns"></param>
        /// <returns></returns>
        public WhereHelper<T1> RemoveColumn(string columns)
        {
            var cols = columns.Split(',');
            foreach (var col in cols) {
                excludeColumn(col);
            }
            return this;
        }
        /// <summary>
        /// 包含列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="column"></param>
        /// <param name="asName"></param>
        /// <returns></returns>
        public WhereHelper<T1> AddColumn<T>(Expression<Func<T1, T>> column, string asName = null)
        {
            includeColumn(column, asName);
            return this;
        }

        /// <summary>
        /// 包含列
        /// </summary>
        /// <param name="columnSql"></param>
        /// <param name="asName"></param>
        /// <returns></returns>
        public WhereHelper<T1> AddColumn(string columnSql, string asName)
        {
            if (string.IsNullOrEmpty(columnSql)) throw new ArgumentException(nameof(columnSql));
            if (string.IsNullOrEmpty(asName)) throw new ArgumentException(nameof(asName));
            if (jump()) { return this; }

            _includeColumns.Insert(0, new SelectHeader() {
                AsName = asName,
                Table = "t1",
                QuerySql = columnSql
            });
            return this;
        }

        #endregion

        #region 09 获取Sql和args方法
        /// <summary><commit_msg>修改 includeColumn 方法<commit_after>﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using ToolGood.ReadyGo3.LinQ.Expressions;
using ToolGood.ReadyGo3.PetaPoco.Core;

namespace ToolGood.ReadyGo3.LinQ
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T1"></typeparam>
    public partial class WhereHelper<T1>
        where T1 : class, new()
    {
        internal WhereHelper(SqlHelper helper)
        {
            this._sqlhelper = helper;
            this._paramPrefix = DatabaseProvider.Resolve(_sqlhelper._sqlType).GetParameterPrefix(_sqlhelper._connectionString);
            _sqlExpression = new Expressions.SqlExpression(_sqlhelper._sqlType);
        }
        #region  01 私有变量
        private SqlExpression _sqlExpression;
        private readonly SqlHelper _sqlhelper;
        private List<object> _args = new List<object>();
        private StringBuilder _where = new StringBuilder();
        private string _joinOnString = "";
        private List<SelectHeader> _includeColumns = new List<SelectHeader>();
        private List<string> _excludeColumns = new List<string>();
        private readonly string _paramPrefix;

        private string _order = "";
        private string _groupby = "";
        private string _having = "";
        private bool _useDistinct = false;
        #endregion

        #region 02 SQL拼接 基础方法

        private bool _doNext = true;

        private bool jump()
        {
            if (_doNext == false) {
                _doNext = true;
                return true;
            }
            return false;
        }

        private void ifTrue(bool iftrue)
        {
            _doNext = iftrue;
        }

        private void whereNotIn(LambdaExpression field, ICollection args)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(field);
            whereNotIn(column, args);
        }

        private void whereNotIn(string column, ICollection args)
        {
            if (jump()) return;

            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            if (args.Count == 0) {
                _where.Append("1=1");
                return;
            }
            _where.Append(column);
            if (args.Count == 1) {
                _where.Append(" <> ");
                _where.Append(_paramPrefix);
                _where.Append(_args.Count.ToString());
            } else {
                _where.Append(" NOT IN (");
                for (int i = 0; i < args.Count; i++) {
                    if (i > 0) {
                        _where.Append(",");
                    }
                    _where.Append(_paramPrefix);
                    _where.Append((_args.Count + i).ToString());
                }
                _where.Append(")");
            }
            foreach (var item in args) {
                _args.Add(item);
            }
        }

        private void whereIn(LambdaExpression field, ICollection args)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(field);
            whereIn(column, args);
        }

        private void whereIn(string column, ICollection args)
        {
            if (jump()) return;

            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            if (args.Count == 0) {
                _where.Append("1=2");
                return;
            }
            _where.Append(column);
            if (args.Count == 1) {
                _where.Append(" = ");
                _where.Append(_paramPrefix);
                _where.Append(_args.Count.ToString());
            } else {
                _where.Append(" IN (");
                for (int i = 0; i < args.Count; i++) {
                    if (i > 0) {
                        _where.Append(",");
                    }
                    _where.Append(_paramPrefix);
                    _where.Append((_args.Count + i).ToString());
                }
                _where.Append(")");
            }
            foreach (var item in args) {
                _args.Add(item);
            }
        }


        internal void where(string where, ICollection args)
        {
            if (jump()) return;
            where = where.Trim();
            if (_where.Length > 0) _where.Append(" AND ");

            int start = 0;
            if (where.StartsWith("where ", StringComparison.CurrentCultureIgnoreCase)) start = 6;

            bool isInText = false, isStart = false;
            var c = 'a';
            var text = "";

            for (int i = start; i < where.Length; i++) {
                var t = where[i];
                if (isInText) {
                    if (t == c) isInText = false;
                } else if ("\"'`".Contains(t)) {
                    isInText = true;
                    c = t;
                    isStart = false;
                } else if (isStart == false) {
                    if (t == '@') {
                        isStart = true;
                        text = "@";
                        continue;
                    }
                } else if ("@1234567890".Contains(t)) {
                    text += t;
                    continue;
                } else {
                    whereTranslate(_where, text);
                    isStart = false;
                }
                _where.Append(t);
            }
            if (isStart) whereTranslate(_where, text);


            foreach (var item in args) {
                _args.Add(item);
            }
        }
        private void whereTranslate(StringBuilder where, string text)
        {
            if (text == "@@") {
                where.Append("@@");
            } else if (text.Length == 1) {
                where.Append(text);
            } else if (text.StartsWith("@")) {
                int p = this._args.Count + int.Parse(text.Replace("@", ""));
                where.Append(_paramPrefix);
                where.Append(p.ToString());
            } else {
                int p = int.Parse(text.Replace("@", ""));
                where.Append(_paramPrefix);
                where.Append(p.ToString());
            }
        }

        private void where(LambdaExpression where)
        {
            if (jump()) return;
            _sqlExpression.Analysis(where, out string sql);
            if (_where.Length > 0) {
                _where.Append(" AND ");
            }
            _where.Append(sql);
        }

        private void join(string join)
        {
            if (jump()) return;
            _joinOnString += " " + join;
        }

        private void includeColumn(LambdaExpression column, string asName)
        {
            if (jump()) return;
            var col = _sqlExpression.GetColumnName(column);
            includeColumn(col, asName);
        }
        private void includeColumn(string col, string asName)
        {
            if (jump()) return;
            var index = col.IndexOf('.');
            string table = null;
            if (index > -1) {
                table = col.Substring(0, index);
                col = col.Substring(index + 1);
            }
            if (string.IsNullOrWhiteSpace(asName)) {
                _includeColumns.Insert(0, new SelectHeader() {
                    AsName = col,
                    Table = table,
                    QuerySql = col
                });
            } else {
                _includeColumns.Insert(0, new SelectHeader() {
                    AsName = asName,
                    Table = table,
                    QuerySql = col,
                    UseAsName = true,
                });
            }

        }

        private void excludeColumn(LambdaExpression column)
        {
            if (jump()) return;
            var col = _sqlExpression.GetColumnName(column);
            excludeColumn(col);
        }
        private void excludeColumn(string col)
        {
            if (jump()) return;
            var index = col.IndexOf('.');
            if (index > -1) {
                col = col.Substring(index + 1);
            }
            _excludeColumns.Add(col);
        }


        private void orderBy(LambdaExpression order, OrderType type)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(order);
            if (type == OrderType.Asc) {
                orderBySql(column + " ASC");
            } else {
                orderBySql(column + " DESC");
            }
        }

        private void orderBySql(string order)
        {
            if (jump()) return;
            if (_order.Length > 0) {
                _order += ",";
            }
            _order += order;
        }

        private void groupBy(LambdaExpression group)
        {
            if (jump()) return;
            var column = _sqlExpression.GetColumnName(group);
            this.groupBy(column);
        }

        private void groupBy(string groupby)
        {
            if (jump()) return;
            groupby = groupby.Trim().Trim(',');
            if (groupby.StartsWith("group by ", StringComparison.CurrentCultureIgnoreCase))
                groupby = groupby.Substring(9).Trim();
            if (string.IsNullOrWhiteSpace(groupby)) return;
            if (_groupby.Length > 0) {
                _groupby += ",";
            }
            _groupby += groupby;
        }
        private void having(LambdaExpression having)
        {
            if (jump()) return;
            _sqlExpression.Analysis(having, out string sql);
            this.having(sql);
        }
        private void having(string having)
        {
            if (jump()) return;
            having = having.Trim().Trim(',');
            if (having.StartsWith("having ", StringComparison.CurrentCultureIgnoreCase))
                having = having.Substring(7).Trim();

            if (string.IsNullOrWhiteSpace(having)) return;
            if (_having.Length > 0) {
                _having += ",";
            }
            _having += having;
        }
        #endregion SQL拼接方法

        #region 03 判断

        /// <summary>
        /// IfTrue 如果为假会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="ifTrue"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfTrue(bool ifTrue)
        {
            this.ifTrue(ifTrue);
            return this;
        }

        /// <summary>
        /// IfFalse 如果为真会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="ifTrue"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfFalse(bool ifTrue)
        {
            this.ifTrue(ifTrue == false);
            return this;
        }

        /// <summary>
        /// IfSet  如果字符串未设置，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfSet(string txt)
        {
            this.ifTrue(string.IsNullOrEmpty(txt) == false);
            return this;
        }

        /// <summary>
        /// IfNotSet  如果字符串已设置，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotSet(string txt)
        {
            this.ifTrue(string.IsNullOrEmpty(txt));
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(string txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(string txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(short? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(short? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(int? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(int? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(long? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(long? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(ushort? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(ushort? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(uint? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(uint? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(ulong? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(ulong? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(float? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(float? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(double? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(double? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(decimal? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(decimal? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        /// <summary>
        /// IfNull  如果字符串不为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNull(DateTime? txt)
        {
            this.ifTrue(txt == null);
            return this;
        }

        /// <summary>
        /// IfNotNull  如果字符串为空，会影响 Where、OrderBy、AddSelect GroupBy Having On方法
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        public WhereHelper<T1> IfNotNull(DateTime? txt)
        {
            this.ifTrue(txt != null);
            return this;
        }

        #endregion 判断

        #region 04 Sql 拼接
        /// <summary>
        /// 自动添加 “NOT EXISTS ” 也会自动添加 “SELECT * ”
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotExists(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            where = where.TrimStart();
            if (where.StartsWith("NOT EXISTS ", StringComparison.CurrentCultureIgnoreCase) == false) {
                if (where.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase) == false) {
                    where = $"NOT EXISTS(SELECT * {@where})";
                } else {
                    where = $"NOT EXISTS({@where})";
                }
            }
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 自动添加 “EXISTS ” 也会自动添加 “SELECT * ”
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereExists(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            where = where.TrimStart();
            if (where.StartsWith("EXISTS ", StringComparison.CurrentCultureIgnoreCase) == false) {
                if (where.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase) == false) {
                    where = $"EXISTS(SELECT * {@where})";
                } else {
                    where = $"EXISTS({@where})";
                }
            }
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="where"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> Where(string where, params object[] args)
        {
            if (string.IsNullOrEmpty(where)) throw new ArgumentNullException("where");
            this.where(where, args);
            return this;
        }
        /// <summary>
        /// 添加 Order By SQL语句
        /// </summary>
        /// <param name="order"></param>
        /// <returns></returns>
        public WhereHelper<T1> OrderBy(string order)
        {
            if (string.IsNullOrEmpty(order)) throw new ArgumentNullException("order");
            this.orderBySql(order);
            return this;
        }
        /// <summary>
        /// 添加 Group By SQL语句
        /// </summary>
        /// <param name="groupby"></param>
        /// <returns></returns>
        public WhereHelper<T1> GroupBy(string groupby)
        {
            if (string.IsNullOrEmpty(groupby)) throw new ArgumentNullException("groupby");
            this.groupBy(groupby);
            return this;
        }
        /// <summary>
        /// 添加 Having SQL语句
        /// </summary>
        /// <param name="having"></param>
        /// <returns></returns>
        public WhereHelper<T1> Having(string having)
        {
            if (string.IsNullOrEmpty(having)) throw new ArgumentNullException("having");
            this.having(having);
            return this;
        }
        /// <summary>
        /// 添加 Join On SQL语句
        /// </summary>
        /// <param name="joinWithOn"></param>
        /// <returns></returns>
        public WhereHelper<T1> JoinOn(string joinWithOn)
        {
            if (string.IsNullOrEmpty(joinWithOn)) throw new ArgumentNullException("joinWithOn");
            this.join(joinWithOn);
            return this;
        }

        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn(string field, ICollection args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereNotIn(field, args);
            return this;
        }

        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn(string field, params object[] args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereNotIn(field, args);
            return this;
        }

        /// <summary>
        /// 添加 Where
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn(string field, ICollection args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereIn(field, args);
            return this;
        }

        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn(string field, params object[] args)
        {
            if (string.IsNullOrEmpty(field)) throw new ArgumentNullException("field");
            this.whereIn(field, args);
            return this;
        }

        #endregion Sql 拼接

        #region 05 Sql拼接 LINQ WhereIn Where OrderBy Having
        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn<T>(Expression<Func<T1, T>> field, ICollection args)
        {
            this.whereNotIn(field, args);
            return this;
        }
        /// <summary>
        /// Where not In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereNotIn<T>(Expression<Func<T1, T>> field, params object[] args)
        {
            return WhereNotIn(field, (ICollection)args);
        }
        /// <summary>
        /// Where  In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn<T>(Expression<Func<T1, T>> field, ICollection args)
        {
            this.whereIn(field, args);
            return this;
        }
        /// <summary>
        /// Where  In
        /// </summary>
        /// <param name="field"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public WhereHelper<T1> WhereIn<T>(Expression<Func<T1, T>> field, params object[] args)
        {
            return WhereIn(field, (ICollection)args);
        }
        /// <summary>
        /// Where
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public WhereHelper<T1> Where(Expression<Func<T1, bool>> where)
        {
            this.where(where);
            return this;
        }
        /// <summary>
        /// OrderBy
        /// </summary>
        /// <param name="order"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public WhereHelper<T1> OrderBy<T>(Expression<Func<T1, T>> order, OrderType type = OrderType.Asc)
        {
            this.orderBy(order, type);
            return this;
        }
        /// <summary>
        /// GroupBy
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public WhereHelper<T1> GroupBy<T>(Expression<Func<T1, T>> group)
        {
            groupBy(group);
            return this;
        }
        /// <summary>
        /// Having
        /// </summary>
        /// <param name="having"></param>
        /// <returns></returns>
        public WhereHelper<T1> Having(Expression<Func<T1, bool>> having)
        {
            this.having(having);
            return this;
        }

        /// <summary>
        /// 非重复
        /// </summary>
        /// <param name="distinct"></param>
        /// <returns></returns>
        public WhereHelper<T1> Distinct(bool distinct = true)
        {
            _useDistinct = distinct;
            return this;
        }

        #endregion WhereIn Where OrderBy Having

        #region 06 查询 Select Page SkipTake Single SingleOrDefault First FirstOrDefault


        #region Select Page SkipTake Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(string selectSql = null)
        {
            return _sqlhelper.Select<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="limit"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(long limit, string selectSql = null)
        {
            return _sqlhelper.Select<T1>(limit, 0, GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T1> Select(long skip, long take, string selectSql = null)
        {
            return _sqlhelper.Select<T1>(skip, take, GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回Page
        /// </summary>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public Page<T1> Page(long page, long itemsPerPage, string selectSql = null)
        {
            return _sqlhelper.Page<T1>(page, itemsPerPage, GetFullSelectSql(selectSql), _args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 Single(string selectSql = null)
        {
            return _sqlhelper.Single<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 SingleOrDefault(string selectSql = null)
        {
            return _sqlhelper.SingleOrDefault<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 First(string selectSql = null)
        {
            return _sqlhelper.First<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T1 FirstOrDefault(string selectSql = null)
        {
            return _sqlhelper.FirstOrDefault<T1>(GetFullSelectSql(selectSql), _args.ToArray());
        }

        #endregion Select Page SkipTake Single SingleOrDefault First FirstOrDefault

        #region Select Page SkipTake Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="limit"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(long limit, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(limit, GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 查询 返回列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public List<T> Select<T>(long skip, long take, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Select<T>(skip, take, GetFullSelectSql(sql), _args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T Single<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Single<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T SingleOrDefault<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.SingleOrDefault<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T First<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.First<T>(GetFullSelectSql(sql), _args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="columns"></param>
        /// <returns></returns>
        public T FirstOrDefault<T>(Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.FirstOrDefault<T>(GetFullSelectSql(sql), _args.ToArray());
        }

        /// <summary>
        /// 查询 返回Page
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public Page<T> Page<T>(long page, long itemsPerPage, Expression<Func<T1, T>> columns)
        {
            _sqlExpression.GetColumns(columns, out string sql);
            return _sqlhelper.Page<T>(page, itemsPerPage, GetFullSelectSql(sql), _args.ToArray());
        }

        #endregion
        #endregion

        #region 07 查询  Count ExecuteDataTable ExecuteDataSet Select Page Single SingleOrDefault First FirstOrDefault
        /// <summary>
        /// 获取数量
        /// </summary>
        /// <param name="selectSql"></param>
        /// <param name="distinct"></param>
        /// <returns></returns>
        public int SelectCount(string selectSql = null, bool distinct = false)
        {
            return this._sqlhelper.getDatabase().ExecuteScalar<int>(this.GetCountSql(selectSql, distinct), this._args.ToArray());
        }
        /// <summary>
        /// 执行返回DataTable
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public DataTable ExecuteDataTable(string selectSql = null)
        {
            return this._sqlhelper.ExecuteDataTable(this.GetFullSelectSql(selectSql), this._args.ToArray());
        }
        //#if !NETSTANDARD2_0
        /// <summary>
        /// 执行返回DataSet
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public DataSet ExecuteDataSet(string selectSql = null)
        {
            return this._sqlhelper.ExecuteDataSet(this.GetFullSelectSql(selectSql), this._args.ToArray());
        }
        //#endif
        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="limit"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(long limit, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(limit, 0, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 执行返回集合
        /// </summary>
        /// <param name="skip"></param>
        /// <param name="take"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public List<T> Select<T>(long skip, long take, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Select<T>(skip, take, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T Single<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Single<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回唯一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T SingleOrDefault<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.SingleOrDefault<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }

        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T First<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.First<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回第一列
        /// </summary>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public T FirstOrDefault<T>(string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.FirstOrDefault<T>(this.GetFullSelectSql(sql), this._args.ToArray());
        }
        /// <summary>
        /// 返回页，page类
        /// </summary>
        /// <param name="page"></param>
        /// <param name="itemsPerPage"></param>
        /// <param name="selectSql"></param>
        /// <returns></returns>
        public Page<T> Page<T>(long page, long itemsPerPage, string selectSql = null)
        {
            var sql = getSelect<T>(selectSql);
            return this._sqlhelper.Page<T>(page, itemsPerPage, this.GetFullSelectSql(sql), this._args.ToArray());
        }

        private string getSelect<T>(string selectSql)
        {
            if (string.IsNullOrEmpty(selectSql) == false) {
                if (selectSql.StartsWith("Select", StringComparison.CurrentCultureIgnoreCase)) {
                    return selectSql;
                }
                return "SELECT " + selectSql;
            }
            return CreateSelectHeader(typeof(T), this._includeColumns);
        }
        #endregion

        #region 08 包含列 排除列
        /// <summary>
        /// 排除列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="column"></param>
        /// <returns></returns>
        public WhereHelper<T1> RemoveColumn<T>(Expression<Func<T1, T>> column)
        {
            excludeColumn(column);
            return this;
        }
        /// <summary>
        /// 排除列
        /// </summary>
        /// <param name="columns"></param>
        /// <returns></returns>
        public WhereHelper<T1> RemoveColumn(string columns)
        {
            var cols = columns.Split(',');
            foreach (var col in cols) {
                excludeColumn(col);
            }
            return this;
        }
        /// <summary>
        /// 包含列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="column"></param>
        /// <param name="asName"></param>
        /// <returns></returns>
        public WhereHelper<T1> AddColumn<T>(Expression<Func<T1, T>> column, string asName = null)
        {
            includeColumn(column, asName);
            return this;
        }

        /// <summary>
        /// 包含列
        /// </summary>
        /// <param name="columnSql"></param>
        /// <param name="asName"></param>
        /// <returns></returns>
        public WhereHelper<T1> AddColumn(string columnSql, string asName)
        {
            if (string.IsNullOrEmpty(columnSql)) throw new ArgumentException(nameof(columnSql));
            if (string.IsNullOrEmpty(asName)) throw new ArgumentException(nameof(asName));
            if (jump()) { return this; }

            _includeColumns.Insert(0, new SelectHeader() {
                AsName = asName,
                Table = "t1",
                QuerySql = columnSql,
                UseAsName = true
            });
            return this;
        }

        #endregion

        #region 09 获取Sql和args方法
        /// <summary>
{'fraction_non_alphanumeric': 0.14553278888943225, 'fraction_numerical': 0.003789916377328965, 'mean_word_length': 1.487743309002433, 'pattern_counts': {'":': 0, '<': 1431, '<?xml version=': 0, '>': 1447, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4109952', 'n_tokens_mistral': 22964, 'n_tokens_neox': 22712, 'n_words': 4564}