using System;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using Dapper;
using DapperExtensions;
using DapperExtensions.Mapper;
using DapperExtensions.Sql;
using DapperExtensions.ValueObject;
using Mall.DataAccess;
using System.Configuration;
using Mall.DataAccess.Utils;

namespace DapperExtensions.Lambda
{
    /// <summary>
    /// LambdaQuery帮助类泛型
    /// </summary>
    /// <typeparam name="T">约束</typeparam>
    public class LambdaQueryHelper<T> : LambdaQueryHelper where T : class
    {

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connection">数据库连接</param>
        /// <param name="transaction">事务</param>
        /// <param name="classMap">数据库配置接口对象</param>
        /// <param name="commandTimeout">超时时间</param>
        public LambdaQueryHelper(IDbConnection connection, IDbTransaction transaction, IClassMapper classMap, int? commandTimeout = null)
            : base(connection, transaction, classMap, commandTimeout)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="classMap">数据库配置接口对象</param>
        /// <param name="commandTimeout">超时时间</param>

        public LambdaQueryHelper(string connKey, IClassMapper classMap, int? commandTimeout = null)
            : base(connKey, classMap, commandTimeout)
        {
        }

        #region Sql组装  Select  OrderBy  Group ……



        #region Select

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="select">查询接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select(ISelect select)
        {
            return (LambdaQueryHelper<T>)base.Select(select.Fields.ToArray());
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="select">查询接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select(ISelect<T> select)
        {
            return (LambdaQueryHelper<T>)base.Select(select.Fields.ToArray());
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select(Expression<Func<T, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">表达式</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2>(Expression<Func<T, T2, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3>(Expression<Func<T, T2, T3, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4>(Expression<Func<T, T2, T3, T4, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select(Expression<Func<T, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2>(Expression<Func<T, T2, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Select<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.Select(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="select">查询接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect(ISelect select)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(select.Fields.ToArray());
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="select">查询接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect(ISelect<T> select)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(select.Fields.ToArray());
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="lambdaSelect">查询接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect(Expression<Func<T, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2>(Expression<Func<T, T2, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3>(Expression<Func<T, T2, T3, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4>(Expression<Func<T, T2, T3, T4, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, bool>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect(Expression<Func<T, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2>(Expression<Func<T, T2, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }

        /// <summary>
        /// 新增查询
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaSelect">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddSelect<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaSelect)
        {
            return (LambdaQueryHelper<T>)base.AddSelect(ExpressionToClip<T>.ToSelect(lambdaSelect));
        }
        #endregion

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <param name="where">WHERE接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where(IWhere where)
        {
            return (LambdaQueryHelper<T>)base.Where(where.ToWhereClip());
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <param name="where">WHERE接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where(IWhere<T> where)
        {
            return (LambdaQueryHelper<T>)base.Where(where.ToWhereClip());
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where(Expression<Func<T, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where<T2>(Expression<Func<T, T2, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where<T2, T3>(Expression<Func<T, T2, T3, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where<T2, T3, T4>(Expression<Func<T, T2, T3, T4, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }

        /// <summary>
        /// 新增Where
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Where<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, bool>> lambdaWhere)
        {
            return (LambdaQueryHelper<T>)Where(ExpressionToClip<T>.ToWhereClip(lambdaWhere));
        }


        /// <summary>
        /// 新增Having
        /// </summary>
        /// <param name="having">WHERE接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Having(IWhere having)
        {
            return (LambdaQueryHelper<T>)base.Having(having.ToWhereClip());
        }

        /// <summary>
        /// 新增Having
        /// </summary>
        /// <param name="lambdaHaving">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> Having(Expression<Func<T, bool>> lambdaHaving)
        {
            return (LambdaQueryHelper<T>)base.Having(ExpressionToClip<T>.ToWhereClip(lambdaHaving));
        }

        /// <summary>
        /// 去重
        /// </summary>
        /// <returns></returns>
        public new LambdaQueryHelper<T> Distinct()
        {
            return (LambdaQueryHelper<T>)base.Distinct();
        }


        /// <summary>
        /// 是否使用WithNoLock
        /// </summary>
        /// <returns></returns>
        public new LambdaQueryHelper<T> WithNoLock()
        {
            return (LambdaQueryHelper<T>)base.WithNoLock();
        }

        /// <summary>
        /// 取Top
        /// </summary>
        /// <param name="topCount"></param>
        /// <returns></returns>
        public new LambdaQueryHelper<T> Top(int topCount)
        {
            return (LambdaQueryHelper<T>)base.Top(topCount);
        }


        #region OrderBy


        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="orderby">排序接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy(IOrderBy orderby)
        {
            return (LambdaQueryHelper<T>)base.OrderBy(orderby.ToOrderByClip());
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="orderby">排序接口对象</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy(IOrderBy<T> orderby)
        {
            return (LambdaQueryHelper<T>)base.OrderBy(orderby.ToOrderByClip());
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy(Expression<Func<T, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }


        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy<T2>(Expression<Func<T, T2, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderBy<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending(Expression<Func<T, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending<T2>(Expression<Func<T, T2, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> OrderByDescending<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)OrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy(Expression<Func<T, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy<T2>(Expression<Func<T, T2, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderBy<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending(Expression<Func<T, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending<T2>(Expression<Func<T, T2, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending<T2, T3>(Expression<Func<T, T2, T3, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending<T2, T3, T4>(Expression<Func<T, T2, T3, T4, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending<T2, T3, T4, T5>(Expression<Func<T, T2, T3, T4, T5, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }

        /// <summary>
        /// 新增倒序
        /// </summary>
        /// <typeparam name="T2">约束</typeparam>
        /// <typeparam name="T3">约束</typeparam>
        /// <typeparam name="T4">约束</typeparam>
        /// <typeparam name="T5">约束</typeparam>
        /// <typeparam name="T6">约束</typeparam>
        /// <param name="lambdaOrderBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> AddOrderByDescending<T2, T3, T4, T5, T6>(Expression<Func<T, T2, T3, T4, T5, T6, object>> lambdaOrderBy)
        {
            return (LambdaQueryHelper<T>)base.AddOrderBy(ExpressionToClip<T>.ToOrderByClip(lambdaOrderBy, OrderByType.DESC));
        }
        #endregion


        /// <summary>
        /// 新增GroupBy
        /// </summary>
        /// <param name="lambdaGroupBy">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> GroupBy(Expression<Func<T, object>> lambdaGroupBy)
        {
            return (LambdaQueryHelper<T>)base.GroupBy(ExpressionToClip<T>.ToGroupByClip(lambdaGroupBy));
        }

        #endregion

        #region Join

        /// <summary>
        /// 新增Join
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="where">where条件</param>
        /// <param name="joinType">连接类型枚举</param>
        /// <returns></returns>
        private new LambdaQueryHelper<T> Join(string tableName, WhereClip where, JoinType joinType)
        {
            return (LambdaQueryHelper<T>)base.Join(tableName, where, joinType);
        }


        /// <summary>
        /// 新增InnerJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="where">where条件</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> InnerJoin<TEntity>(WhereClip where) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, where, JoinType.InnerJoin);
        }

        /// <summary>
        /// 新增InnerJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> InnerJoin<TEntity>(Expression<Func<T, TEntity, bool>> lambdaWhere) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, ExpressionToClip<T>.ToJoinWhere(lambdaWhere), JoinType.InnerJoin);
        }


        /// <summary>
        /// 新增InnerJoin
        /// </summary>
        /// <typeparam name="T1">约束</typeparam>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> InnerJoin<T1, T2>(Expression<Func<T1, T2, bool>> lambdaWhere)
            where T1 : class
            where T2 : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T2>().TableName, ExpressionToClip<T1>.ToJoinWhere(lambdaWhere), JoinType.InnerJoin);
        }


        /// <summary>
        /// 新增LeftJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="where">where条件</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> LeftJoin<TEntity>(WhereClip where) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, where, JoinType.LeftJoin);
        }

        /// <summary>
        /// 新增LeftJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> LeftJoin<TEntity>(Expression<Func<T, TEntity, bool>> lambdaWhere) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, ExpressionToClip<T>.ToJoinWhere(lambdaWhere), JoinType.LeftJoin);
        }

        /// <summary>
        /// 新增LeftJoin
        /// </summary>
        /// <typeparam name="T1">约束</typeparam>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> LeftJoin<T1, T2>(Expression<Func<T1, T2, bool>> lambdaWhere)
            where T1 : class
            where T2 : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T2>().TableName, ExpressionToClip<T1>.ToJoinWhere(lambdaWhere), JoinType.LeftJoin);
        }

        /// <summary>
        /// 新增RightJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="where">where条件</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> RightJoin<TEntity>(WhereClip where) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, where, JoinType.RightJoin);
        }

        /// <summary>
        /// 新增RightJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> RightJoin<TEntity>(Expression<Func<T, TEntity, bool>> lambdaWhere) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, ExpressionToClip<T>.ToJoinWhere(lambdaWhere), JoinType.RightJoin);
        }

        /// <summary>
        /// 新增RightJoin
        /// </summary>
        /// <typeparam name="T1">约束</typeparam>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> RightJoin<T1, T2>(Expression<Func<T1, T2, bool>> lambdaWhere)
            where T1 : class
            where T2 : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T2>().TableName, ExpressionToClip<T1>.ToJoinWhere(lambdaWhere), JoinType.RightJoin);
        }

        /// <summary>
        /// 新增CrossJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="where">where条件</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> CrossJoin<TEntity>(WhereClip where) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, where, JoinType.CrossJoin);
        }

        /// <summary>
        /// 新增CrossJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> CrossJoin<TEntity>(Expression<Func<T, TEntity, bool>> lambdaWhere) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, ExpressionToClip<T>.ToJoinWhere(lambdaWhere), JoinType.CrossJoin);
        }

        /// <summary>
        /// 新增CrossJoin
        /// </summary>
        /// <typeparam name="T1">约束</typeparam>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> CrossJoin<T1, T2>(Expression<Func<T1, T2, bool>> lambdaWhere)
            where T1 : class
            where T2 : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T2>().TableName, ExpressionToClip<T1>.ToJoinWhere(lambdaWhere), JoinType.CrossJoin);
        }

        /// <summary>
        /// 新增FullJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="where">where条件</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> FullJoin<TEntity>(WhereClip where) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, where, JoinType.FullJoin);
        }

        /// <summary>
        /// 新增FullJoin
        /// </summary>
        /// <typeparam name="TEntity">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> FullJoin<TEntity>(Expression<Func<T, TEntity, bool>> lambdaWhere) where TEntity : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<TEntity>().TableName, ExpressionToClip<T>.ToJoinWhere(lambdaWhere), JoinType.FullJoin);
        }

        /// <summary>
        /// 新增FullJoin
        /// </summary>
        /// <typeparam name="T1">约束</typeparam>
        /// <typeparam name="T2">约束</typeparam>
        /// <param name="lambdaWhere">表达式</param>
        /// <returns></returns>
        public LambdaQueryHelper<T> FullJoin<T1, T2>(Expression<Func<T1, T2, bool>> lambdaWhere)
            where T1 : class
            where T2 : class
        {
            return Join(DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T2>().TableName, ExpressionToClip<T1>.ToJoinWhere(lambdaWhere), JoinType.FullJoin);
        }
        #endregion

        #region Execute

        /// <summary>
        /// 转DataReader
        /// </summary>
        /// <returns></returns>
        public new IDataReader ToDataReader()
        {
            return base.ToDataReader();
        }

        /// <summary>
        /// 转ToDataSet
        /// </summary>
        /// <returns></returns>
        public new DataSet ToDataSet()
        {
            return base.ToDataSet();
        }

        /// <summary>
        /// 转PageDataSet
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public new DataSet ToPageDataSet(int pageIndex, int pageSize)
        {
            return base.ToPageDataSet(pageIndex, pageSize);
        }

        /// <summary>
        /// 转DataTable
        /// </summary>
        /// <returns></returns>
        public new DataTable ToDataTable()
        {
            return base.ToDataTable();
        }

        /// <summary>
        /// 转List
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> ToList()
        {
            return base.ToList<T>();
        }

        /// <summary>
        /// 转PageList
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public IEnumerable<T> ToPageList(int pageIndex, int pageSize)
        {
            return base.ToPageList<T>(pageIndex, pageSize);
        }

        /// <summary>
        /// 转PageList
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="allRowsCount">总条数</param>
        /// <returns></returns>
        public IEnumerable<T> ToPageList(int pageIndex, int pageSize, out long allRowsCount)
        {
            return base.ToPageList<T>(pageIndex, pageSize, out allRowsCount);
        }
        #endregion
    }

    /// <summary>
    /// LambdaQuery帮助类
    /// </summary>
    public class LambdaQueryHelper
    {
        #region 属性 变量
        /// <summary>
        /// 数据库配置接口对象
        /// </summary>
        public IClassMapper ClassMap { get; private set; }

        /// <summary>
        /// 连接对象
        /// </summary>
        public IDbConnection Connection { get; private set; }

        /// <summary>
        /// 连接字符串Key
        /// </summary>
        public string ConnKey { get; private set; }

        /// <summary>
        /// 事务对象
        /// </summary>
        public IDbTransaction Transaction { get; private set; }

        /// <summary>
        /// 数据库类型枚举
        /// </summary>
        public DataBaseType DbType { get; private set; }

        /// <summary>
        /// 超时时间
        /// </summary>
        [DefaultValue(30000)]
        public int CommandTimeout { get; private set; }

        /// <summary>
        /// 页码
        /// </summary>
        public int? PageIndex { get; private set; }

        /// <summary>
        /// 页大小
        /// </summary>
        public int? PageSize { get; private set; }

        /// <summary>
        /// 去重
        /// </summary>
        public string DistinctString { get; private set; }

        /// <summary>
        /// 是否使用NoLock
        /// </summary>
        [DefaultValue(false)]
        public bool EnabledNoLock { get; private set; }

        private string _SqlString = string.Empty;
        private WhereClip _WhereClip = WhereClip.All;
        private WhereClip _HavingClip = WhereClip.All;
        private OrderByClip _OrderByClip = OrderByClip.None;
        private GroupByClip _GroupByClip = GroupByClip.None;
        private Dictionary<string, KeyValuePair<string, WhereClip>> _Joins = new Dictionary<string, KeyValuePair<string, WhereClip>>();
        private List<Field> _Fields = new List<Field>();
        private Dictionary<string, Parameter> _Parameters = new Dictionary<string, Parameter>();

        /// <summary>
        /// WHERE条件
        /// </summary>
        public WhereClip WhereClip
        {
            get { return _WhereClip; }
            private set { _WhereClip = value; }
        }

        /// <summary>
        /// Having_WHERE条件
        /// </summary>
        public WhereClip HavingClip
        {
            get { return _HavingClip; }
            private set { _HavingClip = value; }
        }

        /// <summary>
        /// 排序条件
        /// </summary>
        public OrderByClip OrderByClip
        {
            get { return _OrderByClip; }
            private set { _OrderByClip = value; }
        }

        /// <summary>
        /// 分组条件
        /// </summary>
        public GroupByClip GroupByClip
        {
            get { return _GroupByClip; }
            private set { _GroupByClip = value; }
        }

        /// <summary>
        /// 表连接字典
        /// </summary>
        public Dictionary<string, KeyValuePair<string, WhereClip>> Joins
        {
            get { return _Joins; }
            private set { _Joins = value; }
        }

        /// <summary>
        /// 字段集合
        /// </summary>
        public List<Field> Fields
        {
            get { return _Fields; }
            private set { _Fields = value; }
        }

        /// <summary>
        /// 参数字典
        /// </summary>
        public Dictionary<string, Parameter> Parameters
        {
            get
            {
                LoadParameters();
                return _Parameters;
            }
            internal set
            {
                this._Parameters = value;
            }
        }


        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connection">连接对象</param>
        /// <param name="transaction">事务对象</param>
        /// <param name="classMap">数据库配置接口对象</param>
        /// <param name="commandTimeout">超时时间</param>
        public LambdaQueryHelper(IDbConnection connection, IDbTransaction transaction, IClassMapper classMap, int? commandTimeout = null)
        {
            this.Connection = connection;
            this.DbType = DapperExtension.DapperImplementor.DbType;
            this.Transaction = transaction;
            this.ClassMap = classMap;
            if (null != commandTimeout)
            {
                this.CommandTimeout = CommandTimeout;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="connKey">连接字符串Key</param>
        /// <param name="classMap">数据库配置接口对象</param>
        /// <param name="commandTimeout">超时时间</param>
        public LambdaQueryHelper(string connKey, IClassMapper classMap, int? commandTimeout = null)
        {
            this.ConnKey = connKey;
            this.DbType = DBUtils.GetDBTypeByConnKey(connKey);
            this.ClassMap = classMap;
            if (null != commandTimeout)
            {
                this.CommandTimeout = CommandTimeout;
            }
        }


        #endregion

        #region Sql组装  Select  OrderBy  Group ……


        /// <summary>
        /// 查询条件赋值
        /// </summary>
        /// <param name="fields">字段数组</param>
        /// <returns></returns>
        public LambdaQueryHelper Select(params Field[] fields)
        {
            IsChangeSql();
            this._Fields.Clear();
            return AddSelect(fields);
        }

        /// <summary>
        /// 增加查询条件
        /// </summary>
        /// <param name="fields">字段数组</param>
        /// <returns></returns>
        public LambdaQueryHelper AddSelect(params Field[] fields)
        {
            if (null != fields && fields.Length > 0)
            {
                IsChangeSql();
                foreach (Field field in fields)
                {
                    Field f = this._Fields.Find(fi => fi.Name.Equals(field.Name) && fi.TableName.Equals(field.TableName));
                    if (Field.IsNullOrEmpty(f))
                        this._Fields.Add(field);
                }
            }
            return this;
        }


        /// <summary>
        /// 新增查询
        /// </summary>
        /// <param name="where">WHERE条件</param>
        /// <returns></returns>
        protected LambdaQueryHelper Where(WhereClip where)
        {
            IsChangeSql();
            this._WhereClip = where;
            return this;
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="orderBy">排序条件</param>
        /// <returns></returns>
        protected LambdaQueryHelper OrderBy(OrderByClip orderBy)
        {
            IsChangeSql();
            this._OrderByClip = orderBy;
            return this;
        }

        /// <summary>
        /// 新增排序
        /// </summary>
        /// <param name="orderBy">排序条件</param>
        /// <returns></returns>
        protected LambdaQueryHelper AddOrderBy(OrderByClip orderBy)
        {
            IsChangeSql();
            this._OrderByClip = this._OrderByClip && orderBy; ;
            return this;
        }

        /// <summary>
        /// 新增分组
        /// </summary>
        /// <param name="groupBy">分组条件</param>
        /// <returns></returns>
        public LambdaQueryHelper GroupBy(GroupByClip groupBy)
        {
            IsChangeSql();
            this._GroupByClip = groupBy;
            return this;
        }

        /// <summary>
        /// 新增过滤(Having)
        /// </summary>
        /// <param name="havingWhere">WHERE条件</param>
        /// <returns></returns>
        public LambdaQueryHelper Having(WhereClip havingWhere)
        {
            IsChangeSql();
            this._HavingClip = havingWhere;
            return this;
        }

        /// <summary>
        /// 去重
        /// </summary>
        /// <returns></returns>
        public LambdaQueryHelper Distinct()
        {
            IsChangeSql();
            this.DistinctString = " DISTINCT ";
            return this;
        }

        /// <summary>
        /// 是否使用WithNoLock
        /// </summary>
        /// <returns></returns>
        public LambdaQueryHelper WithNoLock()
        {
            IsChangeSql();
            this.EnabledNoLock = true;
            return this;
        }

        /// <summary>
        ///  获取Top
        /// </summary>
        /// <param name="topCount"></param>
        /// <returns></returns>
        public LambdaQueryHelper Top(int topCount)
        {
            if (topCount > 0)
            {
                IsChangeSql();
                this.PageIndex = 1;
                this.PageSize = topCount;
            }
            return this;
        }

        #endregion

        #region  JOIN


        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="where">条件</param>
        /// <param name="joinType">表连接类型枚举</param>
        /// <returns></returns>
        protected LambdaQueryHelper Join(string tableName, WhereClip where, JoinType joinType)
        {
            IsChangeSql();
            if (string.IsNullOrEmpty(tableName) || WhereClip.IsNullOrEmpty(where))
                return this;
            if (!_Joins.ContainsKey(tableName))
            {
                _Joins.Add(tableName, new KeyValuePair<string, WhereClip>(DapperExtension.DapperImplementor.SqlGenerator.Configuration.Dialect.GetJoinString(joinType), where));
                if (where.Parameters.Count > 0)
                {
                    foreach (var item in where.Parameters)
                    {
                        _Parameters.Add(item.ParameterName, item);
                    }
                }
            }
            return this;
        }
        #endregion


        /// <summary>
        ///  获取sql语句
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="loadOrderby">是否加载排序</param>
        /// <param name="reLoadSql">是否重新加载sql</param>
        /// <returns></returns>
        public string GetSqlString(int? pageIndex = null, int? pageSize = null, bool loadOrderby = true, bool reLoadSql = false)
        {
            if (pageIndex != null && pageSize != null)
            {
                ReLoadParameters();
                return DapperExtension.DapperImplementor.SqlGenerator.LambdaSelect(this, ref _Parameters, Convert.ToInt32(pageIndex), Convert.ToInt32(pageSize), loadOrderby);
            }
            else
            {
                if (string.IsNullOrEmpty(_SqlString))
                {
                    ReLoadParameters();
                    _SqlString = DapperExtension.DapperImplementor.SqlGenerator.LambdaSelect(this, ref _Parameters);
                }
                return _SqlString;
            }
        }

        /// <summary>
        /// 获取统计Sql
        /// </summary>
        /// <returns></returns>
        public string GetCountSqlString()
        {
            ReLoadParameters();
            return
                DapperExtension.DapperImplementor.SqlGenerator.PageCount(
                DapperExtension.DapperImplementor.SqlGenerator.LambdaSelect(this, ref _Parameters, null, null, loadOrderby: false));
        }





        #region Execute
        #region ToDataReader

        /// <summary>
        /// 转DataReader
        /// </summary>
        /// <returns></returns>
        public IDataReader ToDataReader()
        {
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbTransaction != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteReader(Transaction, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else if (ConnObj.DbConnection != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteReader(Connection, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else
            {
                return DBUtils.GetDBHelper(DbType).ExecuteReader(ConnKey, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
        }

        #endregion

        /// <summary>
        /// 转DataSet
        /// </summary>
        /// <returns></returns>
        public DataSet ToDataSet()
        {
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbTransaction != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(Transaction, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else if (ConnObj.DbConnection != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(Connection, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(ConnKey, GetSqlString(), DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
        }

        /// <summary>
        /// 转PageDataSet
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public DataSet ToPageDataSet(int pageIndex, int pageSize)
        {
            string sql = GetSqlString(pageIndex, pageSize);
            string sqlcount = GetCountSqlString();

            string execSql = sql + " ; " + sqlcount;
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbTransaction != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(Transaction, execSql, DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else if (ConnObj.DbConnection != null)
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(Connection, execSql, DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
            else
            {
                return DBUtils.GetDBHelper(DbType).ExecuteDataSet(ConnKey, execSql, DBUtils.ConvertToDbParameter(Parameters, DbType));
            }
        }

        /// <summary>
        /// 转DataTable
        /// </summary>
        /// <returns></returns>
        public DataTable ToDataTable()
        {
            return this.ToDataSet().Tables[0];
        }


        /// <summary>
        /// 转List
        /// </summary>
        /// <typeparam name="T">约束</typeparam>
        /// <returns></returns>
        public IEnumerable<T> ToList<T>() where T : class
        {
            string sql = GetSqlString();
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                return Connection.Query<T>(sql, dynamicParameters, Transaction, true, CommandTimeout, CommandType.Text);
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    return conn.Query<T>(sql, dynamicParameters, Transaction, true, CommandTimeout, CommandType.Text);
                }
            }
        }

        /// <summary>
        /// 转PageList
        /// </summary>
        /// <typeparam name="T">约束</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public IEnumerable<T> ToPageList<T>(int pageIndex, int pageSize) where T : class
        {
            string sql = GetSqlString(pageIndex, pageSize);
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                return Connection.Query<T>(sql, dynamicParameters, Transaction, true, CommandTimeout, CommandType.Text);
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    return conn.Query<T>(sql, dynamicParameters, Transaction, true, CommandTimeout, CommandType.Text);
                }
            }
        }

        /// <summary>
        /// 转PageList
        /// </summary>
        /// <typeparam name="T">约束</typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="allRowsCount">总条数</param>
        /// <returns></returns>
        public IEnumerable<T> ToPageList<T>(int pageIndex, int pageSize, out long allRowsCount) where T : class
        {
            allRowsCount = 0;
            string sql = GetSqlString(pageIndex, pageSize);
            string sqlcount = GetCountSqlString();

            string execSql = sql + " ; " + sqlcount;
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                using (var multi = Connection.QueryMultiple(execSql, dynamicParameters, Transaction, CommandTimeout, CommandType.Text))
                {
                    var list = multi.Read<T>();
                    allRowsCount = multi.Read().Single().Total;
                    return list;
                }
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    using (var multi = conn.QueryMultiple(execSql, dynamicParameters, Transaction, CommandTimeout, CommandType.Text))
                    {
                        var list = multi.Read<T>();
                        allRowsCount = multi.Read<long>().Single();
                        return list;
                    }
                }
            }
        }


        /// <summary>
        /// 转List
        /// </summary>
        /// <typeparam name="TFirst">约束</typeparam>
        /// <typeparam name="TSecond">约束</typeparam>
        /// <typeparam name="TReturn">约束</typeparam>
        /// <param name="map">表达式</param>
        /// <param name="splitOn"></param>
        /// <returns></returns>
        public IEnumerable<TReturn> ToList<TFirst, TSecond, TReturn>(Func<TFirst, TSecond, TReturn> map, string splitOn = "Id")
        {
            string sql = GetSqlString();
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                return Connection.Query<TFirst, TSecond, TReturn>(sql, map, dynamicParameters, Transaction, true, splitOn, CommandTimeout, CommandType.Text);
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    return conn.Query<TFirst, TSecond, TReturn>(sql, map, dynamicParameters, Transaction, true, splitOn, CommandTimeout, CommandType.Text);
                }
            }
        }

        /// <summary>
        /// 转List
        /// </summary>
        /// <typeparam name="TFirst">约束</typeparam>
        /// <typeparam name="TSecond">约束</typeparam>
        /// <typeparam name="TThird">约束</typeparam>
        /// <typeparam name="TReturn">约束</typeparam>
        /// <param name="map">表达式</param>
        /// <param name="splitOn"></param>
        /// <returns></returns>
        public IEnumerable<TReturn> ToList<TFirst, TSecond, TThird, TReturn>(Func<TFirst, TSecond, TThird, TReturn> map, string splitOn = "Id")
        {
            string sql = GetSqlString();
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                return Connection.Query<TFirst, TSecond, TThird, TReturn>(sql, map, dynamicParameters, Transaction, true, splitOn, CommandTimeout, CommandType.Text);
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    return conn.Query<TFirst, TSecond, TThird, TReturn>(sql, map, dynamicParameters, Transaction, true, splitOn, CommandTimeout, CommandType.Text);
                }
            }
        }



        /// <summary>
        /// 执行sql 返回总行数    请在 Page方法之前执行
        /// </summary>
        /// <returns></returns>
        public int Count()
        {
            string sql = DapperExtension.DapperImplementor.SqlGenerator.PageCount(GetSqlString());
            DynamicParameters dynamicParameters = new DynamicParameters();
            foreach (var item in Parameters)
            {
                dynamicParameters.Add(item.Value.ParameterName, item.Value.ParameterValue);
            }
            DbConnObj ConnObj = DBUtils.GetConnObj(Connection, Transaction);
            if (ConnObj.DbConnection != null)
            {
                return (int)Connection.Query(sql, dynamicParameters, Transaction, false, CommandTimeout, CommandType.Text).Single().Total;
            }
            else
            {
                using (IDbConnection conn = DBUtils.CreateDBConnection(ConnKey, out DataBaseType dbType))
                {
                    return (int)conn.Query(sql, dynamicParameters, Transaction, false, CommandTimeout, CommandType.Text).Single().Total;
                }
            }
        }
        #endregion

        /// <summary>
        /// 重置
        /// </summary>
        public void Reset()
        {
            PageIndex = null;
            PageSize = null;
            DistinctString = string.Empty;
            EnabledNoLock = false;
            _SqlString = string.Empty;
            _WhereClip = WhereClip.All;
            _HavingClip = WhereClip.All;
            _OrderByClip = OrderByClip.None;
            _GroupByClip = GroupByClip.None;
            _Joins = new Dictionary<string, KeyValuePair<string, WhereClip>>();
            _Fields = new List<Field>();
            _Parameters = new Dictionary<string, Parameter>();
        }


        #region Private方法

        /// <summary>
        /// 是否修改sql
        /// </summary>
        private void IsChangeSql()
        {
            //_Parameters.Clear();
            //LoadParameters();
            _SqlString = string.Empty;
        }


        /// <summary>
        /// 重新加载参数
        /// </summary>
        private void LoadParameters()
        {
            if (null == _Parameters || _Parameters.Count == 0)
            {
                if (!WhereClip.IsNullOrEmpty(_WhereClip))
                {
                    foreach (var item in _WhereClip.Parameters)
                    {
                        _Parameters.Add(item.ParameterName, item);
                    }
                }
                //  处理groupby的having
                if (!GroupByClip.IsNullOrEmpty(_GroupByClip) && !WhereClip.IsNullOrEmpty(_HavingClip))
                {
                    foreach (var item in _HavingClip.Parameters)
                    {
                        _Parameters.Add(item.ParameterName, item);
                    }
                }
                if (_Joins != null && _Joins.Count > 0)
                {
                    foreach (var item in _Joins)
                    {
                        foreach (var p in item.Value.Value.Parameters)
                        {
                            _Parameters.Add(p.ParameterName, p);
                        }
                    }
                }
            }
        }


        private void ReLoadParameters()
        {
            _Parameters.Clear();
            LoadParameters();
        }

        #endregion
    }
}
