using DapperExtensions.Mapper;
using DapperExtensions.Sql;
using DapperExtensions.ValueObject;
using Mall.DataAccess.Utils;
using System;
using System.Collections.Generic;
using System.Text;


namespace DapperExtensions.Lambda
{
    /// <summary>
    /// 字段
    /// </summary>
    [Serializable]
    public class Field : PropertyMap
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public Field() { }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fieldName">字段名称</param>
        public Field(string fieldName) : this(fieldName, "", "") { }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="pm">属性映射接口对象</param>
        public Field(IPropertyMap pm)
            : base(pm)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="pm">属性映射接口对象</param>
        /// <param name="aliasName">别名</param>
        public Field(IPropertyMap pm, string aliasName)
            : base(pm)
        {
            this.AliasName = aliasName;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="fieldName">字段名称</param>
        /// <param name="tableName">表名称</param>
        /// <param name="aliasName">别名</param>
        public Field(string fieldName, string tableName = "", string aliasName = "")
        {
            this.Name = fieldName;
            this.ColumnName = fieldName;
            if (!string.IsNullOrEmpty(tableName))
            {
                this.TableName = tableName;
            }
            if (!string.IsNullOrEmpty(aliasName))
            {
                this.AliasName = aliasName;
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="entityType">实体类型</param>
        public Field(string key, Type entityType)
            : base(key, entityType)
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="entityType">实体类型</param>
        /// <param name="aliasName">别名</param>
        public Field(string key, Type entityType, string aliasName)
            : base(key, entityType)
        {
            if (string.IsNullOrEmpty(aliasName))
            {
                this.AliasName = aliasName;
            }
        }

        /// <summary>
        /// 获取字段
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="entityType">实体类型</param>
        /// <param name="aliasName">别名</param>
        /// <returns></returns>
        public static Field GetField(string key, Type entityType, string aliasName)
        {
            IClassMapper classMapper = DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap(entityType);
            if (classMapper.Properties.ContainsKey(key))
            {
                return new Field(classMapper.Properties[key], aliasName);
            }
            return null;
        }

        /// <summary>
        /// 获取字段
        /// </summary>
        /// <typeparam name="T">约束</typeparam>
        /// <param name="key">键</param>
        /// <param name="aliasName">别名</param>
        /// <returns></returns>
        public static Field GetField<T>(string key, string aliasName = "") where T : class
        {
            IClassMapper classMapper = DapperExtension.DapperImplementor.SqlGenerator.Configuration.GetMap<T>();
            if (classMapper.Properties.ContainsKey(key))
            {
                return new Field(classMapper.Properties[key], aliasName);
            }
            return null;
        }

        /// <summary>
        /// 表字段名称
        /// </summary>
        public string TableFieldName
        {
            get
            {
                return DapperExtension.DapperImplementor.SqlGenerator.Configuration.Dialect.GetColumnName(
                         DapperExtension.DapperImplementor.SqlGenerator.GetTableName(TableName),
                        ColumnName, "");
            }
        }

        /// <summary>
        /// 全称[表名.字段名 AS 别名]
        /// </summary>
        public string FullName
        {
            get
            {
                if (string.IsNullOrEmpty(AliasName))
                    return TableFieldName;

                return string.Concat(TableFieldName, " AS {0}", AliasName, "{1}");
            }
        }


        /// <summary>
        /// 别名
        /// </summary>
        public string AliasName { get; set; }

        /// <summary>
        /// 设置别名
        /// </summary>
        /// <param name="aliasName"></param>
        public void SetAliasName(string aliasName)
        {
            this.AliasName = aliasName;
        }


        #region 属性
        /// <summary>
        /// datepart   year
        /// </summary>
        public Field Year
        {
            get
            {
                return new Field(string.Concat("datepart(year,", this.TableFieldName, ")")).As(this);
            }
        }

        /// <summary>
        /// datepart   month
        /// </summary>
        public Field Month
        {
            get
            {
                return new Field(string.Concat("datepart(month,", this.TableFieldName, ")")).As(this);
            }
        }

        /// <summary>
        /// datepart  day
        /// </summary>
        public Field Day
        {
            get
            {
                return new Field(string.Concat("datepart(day,", this.TableFieldName, ")")).As(this);
            }
        }

        /// <summary>
        /// 倒序
        /// </summary>
        public OrderByClip Desc
        {
            get
            {
                return new OrderByClip(this, OrderByType.DESC);
            }
        }

        /// <summary>
        /// 正序
        /// </summary>
        public OrderByClip Asc
        {
            get
            {
                return new OrderByClip(this, OrderByType.ASC);
            }
        }

        /// <summary>
        /// 分组
        /// </summary>
        public GroupByClip GroupBy
        {
            get
            {
                return new GroupByClip(this);
            }
        }

        #endregion

        #region 方法

        /// <summary>
        /// 重写Equals
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        /// <summary>
        /// 重写GetHashCode
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// 比较
        /// </summary>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public bool Equals(Field field)
        {
            if (null == (object)field)
                return false;
            return this.FullName.Equals(field.FullName);
        }

        /// <summary>
        /// 判断是否为空
        /// </summary>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(Field field)
        {
            if (null == (object)field || string.IsNullOrEmpty(field.ColumnName))
                return true;
            return false;
        }

        /// <summary>
        /// AS
        /// </summary>
        /// <param name="AliasName">别名</param>
        /// <returns></returns>
        public Field As(string AliasName)
        {
            return new Field(this.ColumnName, this.TableName, AliasName);
        }

        /// <summary>
        /// AS
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public Field As(Field field)
        {
            return As(field.Name);
        }

        /// <summary>
        /// 判断字段是否为Null
        /// </summary>
        /// <param name="field">字段实体</param>
        /// <returns></returns>
        public Field IsNull(Field field)
        {
            return new Field(string.Concat("isnull(", this.TableFieldName, ",", field.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// 判断字段是否为Null
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public Field IsNull(object value)
        {
            return new Field(string.Concat("isnull(", this.TableFieldName, ",", DataUtils.FormatValue(value), ")")).As(this);
        }

        /// <summary>
        /// Count
        /// </summary>
        /// <returns></returns>
        public Field Count()
        {
            if (this.ColumnName.Trim().Equals("*"))
                return new Field("count(*)").As("cnt");
            return new Field(string.Concat("count(", this.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// Distinct
        /// </summary>
        /// <returns></returns>
        public Field Distinct()
        {
            if (this.ColumnName.Trim().Equals("*"))
                return this;
            return new Field(string.Concat("distinct ", this.TableFieldName)).As(this);
        }

        /// <summary>
        /// Sum
        /// </summary>
        /// <returns></returns>
        public Field Sum()
        {
            return new Field(string.Concat("sum(", this.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// Avg
        /// </summary>
        /// <returns></returns>
        public Field Avg()
        {
            return new Field(string.Concat("avg(", this.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// len
        /// </summary>
        /// <returns></returns>
        public Field Len()
        {
            return new Field(string.Concat("len(", this.TableFieldName, ")")).As(this);
        }


        /// <summary>
        /// ltrim and  rtrim
        /// </summary>
        /// <returns></returns>
        public Field Trim()
        {
            return new Field(string.Concat("ltrim(rtrim(", this.TableFieldName, "))")).As(this);
        }

        /// <summary>
        /// Max
        /// </summary>
        /// <returns></returns>
        public Field Max()
        {
            return new Field(string.Concat("max(", this.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// Min
        /// </summary>
        /// <returns></returns>
        public Field Min()
        {
            return new Field(string.Concat("min(", this.TableFieldName, ")")).As(this);
        }

        /// <summary>
        /// Left
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public Field Left(int length)
        {
            return new Field(string.Concat("left(", this.TableFieldName, ",", length.ToString(), ")")).As(this);
        }

        /// <summary>
        /// Right
        /// </summary>
        /// <param name="length">长度</param>
        /// <returns></returns>
        public Field Right(int length)
        {
            return new Field(string.Concat("right(", this.TableFieldName, ",", length.ToString(), ")")).As(this);
        }

        /// <summary>
        /// substring
        /// </summary>
        /// <param name="startIndex">开始索引</param>
        /// <param name="endIndex">结束索引</param>
        /// <returns></returns>
        public Field Substring(int startIndex, int endIndex)
        {
            return new Field(string.Concat("substring(", this.TableFieldName, ",", startIndex.ToString(), ",", endIndex.ToString(), ")")).As(this);
        }

        /// <summary>
        /// charindex
        /// </summary>
        /// <param name="subString"></param>
        /// <returns></returns>
        public Field IndexOf(string subString)
        {
            return new Field(string.Concat("charindex(", this.TableFieldName, ",", DataUtils.FormatValue(subString), ") - 1")).As(this);
        }

        /// <summary>
        /// replace
        /// </summary>
        /// <param name="oldValue">替换前值</param>
        /// <param name="newValue">替换值</param>
        /// <returns></returns>
        public Field Replace(string oldValue, string newValue)
        {
            return new Field(string.Concat("replace(", this.TableFieldName, ",", DataUtils.FormatValue(oldValue), ",", DataUtils.FormatValue(newValue), ")")).As(this);
        }

        /// <summary>
        /// 创建whereclip
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <param name="oper"></param>
        /// <returns></returns>
        private static WhereClip CreateWhereClip(Field leftField, Field rightField, QueryOperator oper)
        {
            if (IsNullOrEmpty(leftField) || IsNullOrEmpty(rightField))
                return null;

            return new WhereClip(leftField.TableFieldName + DataUtils.ToString(oper) + rightField.TableFieldName);
        }

        /// <summary>
        /// 创建Field
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <param name="oper"></param>
        /// <returns></returns>
        private static Field CreateField(Field leftField, Field rightField, QueryOperator oper)
        {
            if (IsNullOrEmpty(leftField) && IsNullOrEmpty(rightField))
                return null;

            if (IsNullOrEmpty(leftField))
                return rightField;

            if (IsNullOrEmpty(rightField))
                return leftField;

            return new Field(leftField.TableFieldName + DataUtils.ToString(oper) + rightField.TableFieldName);
        }


        /// <summary>
        /// <![CDATA[&]]>
        /// </summary>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public Field BitwiseAND(Field rightField)
        {
            return CreateField(this, rightField, QueryOperator.BitwiseAND).As(this);
        }

        /// <summary>
        /// |
        /// </summary>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public Field BitwiseOR(Field rightField)
        {
            return CreateField(this, rightField, QueryOperator.BitwiseOR).As(this);
        }

        /// <summary>
        /// ^
        /// </summary>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public Field BitwiseXOR(Field rightField)
        {
            return CreateField(this, rightField, QueryOperator.BitwiseXOR).As(this);
        }

        /// <summary>
        /// ~
        /// </summary>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public Field BitwiseNOT(Field rightField)
        {
            return CreateField(this, rightField, QueryOperator.BitwiseNOT).As(this);
        }


        private static string FormatValue(object value)
        {
            if (null == value)
                return string.Empty;
            return value.ToString();
        }

        /// <summary>
        /// like '%value%' 模糊查询，同Like
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public WhereClip Contain(object value)
        {
            return new WhereClip(this, string.Concat(likeString, value, likeString), QueryOperator.Like);
        }
        /// <summary>
        /// like '%value%' 模糊查询，同  Contain
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public WhereClip Like(object value)
        {
            return Contain(value);
        }
        /// <summary>
        /// BeginWith  
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public WhereClip BeginWith(object value)
        {
            return new WhereClip(this, string.Concat(value, likeString), QueryOperator.Like);
        }

        /// <summary>
        /// EndWith  
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public WhereClip EndWith(object value)
        {
            return new WhereClip(this, string.Concat(likeString, value), QueryOperator.Like);
        }

        /// <summary>
        /// LIKE %
        /// </summary>
        private const string likeString = "%";

        /// <summary>
        /// IN
        /// </summary>
        private const string selectInString = " IN ";

        /// <summary>
        /// NOT IN
        /// </summary>
        private const string selectNotInString = " NOT IN ";

        /// <summary>
        /// 子查询
        /// </summary>
        /// <param name="field"></param>
        /// <param name="join"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        private WhereClip SelectInOrNotIn<T>(Field field, string join, params T[] values)
        {
            return SelectInOrNotIn<T>(field, join, true, values);
        }


        /// <summary>
        /// 子查询
        /// </summary>
        /// <param name="field"></param>
        /// <param name="join"></param>
        /// <param name="isParameter">是否参数化</param>
        /// <param name="values"></param>
        /// <returns></returns>
        private WhereClip SelectInOrNotIn<T>(Field field, string join, bool isParameter, params T[] values)
        {
            if (values.Length == 0)
            {
                return new WhereClip("1=2");
            }
            StringBuilder whereString = new StringBuilder(field.TableFieldName);
            whereString.Append(join);
            whereString.Append("(");
            List<Parameter> ps = new List<Parameter>();
            StringBuilder inWhere = new StringBuilder();
            var i = 0;
            foreach (T value in values)
            {
                i++;
                string paraName = null;
                if (isParameter)
                {
                    paraName = DataUtils.MakeUniqueKey(field);
                    Parameter p = new Parameter(paraName, value);
                    ps.Add(p);
                }
                else
                {
                    if (value == null)
                        continue;
                    paraName = value.ToString();
                    if (string.IsNullOrEmpty(paraName))
                        continue;
                }
                inWhere.Append(",");
                inWhere.Append(paraName);
            }
            whereString.Append(inWhere.ToString().Substring(1));
            whereString.Append(")");
            return new WhereClip(whereString.ToString(), ps.ToArray());
        }

        /// <summary>
        /// SelectIn  
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip SelectIn(params object[] values)
        {
            return SelectInOrNotIn<object>(this, selectInString, values);
        }

        /// <summary>
        /// 同SelectIn。
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip In(params object[] values)
        {
            return SelectIn(values);
        }

        /// <summary>
        /// where field in (value,value,value)。传入Array或List&lt;T>。
        /// </summary>
        /// <param name="values"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public WhereClip SelectIn<T>(params T[] values)
        {
            if (typeof(T) == typeof(int))
            {
                return SelectInOrNotIn<T>(this, selectInString, false, values);
            }

            return SelectInOrNotIn<T>(this, selectInString, values);
        }

        /// <summary>
        /// where field in (value,value,value)。同SelectIn。传入Array或List&lt;T>。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip In<T>(params T[] values)
        {
            return SelectIn(values);
        }

        /// <summary>
        /// where field in (value,value,value)。 传入Array或List&lt;T>。
        /// </summary>
        /// <param name="values"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public WhereClip SelectIn<T>(List<T> values)
        {
            return SelectIn(values.ToArray());
        }

        /// <summary>
        /// where field in (value,value,value)。同SelectIn。传入Array或List&lt;T>。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip In<T>(List<T> values)
        {
            return SelectIn(values.ToArray());
        }

        /// <summary>
        /// where field in (value,value,value)。同In.
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip SelectNotIn(params object[] values)
        {
            return SelectInOrNotIn<object>(this, selectNotInString, values);
        }

        /// <summary>
        /// 同SelectNotIn。
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip NotIn(params object[] values)
        {
            return SelectNotIn(values);
        }

        /// <summary>
        /// SelectNotIn  。传入Array或List&lt;T>。
        /// </summary>
        /// <param name="values"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public WhereClip SelectNotIn<T>(params T[] values)
        {
            if (typeof(T) == typeof(int))
            {
                return SelectInOrNotIn<T>(this, selectNotInString, false, values);
            }
            return SelectInOrNotIn<T>(this, selectNotInString, values);
        }

        /// <summary>
        /// 同SelectNotIn。传入Array或List&lt;T>。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip NotIn<T>(params T[] values)
        {
            return SelectNotIn(values);
        }

        /// <summary>
        /// SelectNotIn。传入Array或List&lt;T>。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip SelectNotIn<T>(List<T> values)
        {
            return SelectNotIn(values.ToArray());
        }

        /// <summary>
        /// 同SelectNotIn。传入Array或List&lt;T>。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="values"></param>
        /// <returns></returns>
        public WhereClip NotIn<T>(List<T> values)
        {
            return SelectNotIn(values.ToArray());
        }
        /// <summary>
        /// SubQueryIn   子查询  
        /// </summary>
        /// <param name="from">LambdaQueryHelper</param>
        /// <returns></returns>
        public WhereClip SubQueryIn(LambdaQueryHelper from)
        {
            return SubQuery(this, from, selectInString);
        }

        /// <summary>
        /// SubQueryNotIn   子查询  
        /// </summary>
        /// <param name="from">LambdaQueryHelper</param>
        /// <returns></returns>
        public WhereClip SubQueryNotIn(LambdaQueryHelper from)
        {
            return SubQuery(this, from, selectNotInString);
        }

        /// <summary>
        /// 组合 子查询
        /// </summary>
        /// <param name="field">字段</param>
        /// <param name="from">LambdaQueryHelper</param>
        /// <param name="oper">比较类型</param>
        /// <returns></returns>
        private WhereClip SubQuery(Field field, LambdaQueryHelper from, QueryOperator oper)
        {
            return SubQuery(field, from, DataUtils.ToString(oper));
        }

        /// <summary>
        /// 组合 子查询    TODO
        /// </summary>
        /// <param name="field">字段</param>
        /// <param name="from">LambdaQueryHelper</param>
        /// <param name="join">连接</param>
        /// <returns></returns>
        private WhereClip SubQuery(Field field, LambdaQueryHelper from, string join)
        {
            if (Field.IsNullOrEmpty(field))
                return null;
            return null;
        }

        /// <summary>
        /// SubQueryEqual   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryEqual(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.Equal);
        }

        /// <summary>
        /// SubQueryNotEqual   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryNotEqual(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.NotEqual);
        }

        /// <summary>
        /// SubQueryLess   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryLess(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.Less);
        }

        /// <summary>
        /// SubQueryLessOrEqual   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryLessOrEqual(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.LessOrEqual);
        }

        /// <summary>
        /// SubQueryGreater   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryGreater(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.Greater);
        }

        /// <summary>
        /// SubQueryGreaterOrEqual   子查询  
        /// </summary>
        /// <param name="from"></param>
        /// <returns></returns>
        public WhereClip SubQueryGreaterOrEqual(LambdaQueryHelper from)
        {
            return SubQuery(this, from, QueryOperator.GreaterOrEqual);
        }

        /// <summary>
        /// 字段 为null <example>field is null</example>
        /// </summary>
        /// <returns></returns>
        public WhereClip IsNull()
        {
            return new WhereClip(string.Concat(this.TableFieldName, " is null "));
        }

        /// <summary>
        /// 字段 为null <example>field is not null</example>
        /// </summary>
        /// <returns></returns>
        public WhereClip IsNotNull()
        {
            return new WhereClip(string.Concat(this.TableFieldName, " is not null "));
        }

        /// <summary>
        /// Between操作
        /// </summary>
        /// <example>
        /// <![CDATA[ a>=value and a<=value ]]>
        /// </example>
        /// <param name="leftValue">左边值</param>
        /// <param name="rightValue">右边值</param>
        /// <returns></returns>
        public WhereClip Between(object leftValue, object rightValue)
        {
            return this >= leftValue && this <= rightValue;
        }


        #region 操作符重载

        #region WhereClip

        /// <summary>
        /// <![CDATA[==]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator ==(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.Equal);
        }

        /// <summary>
        /// <![CDATA[!=]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator !=(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.NotEqual);
        }

        /// <summary>
        /// <![CDATA[>]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator >(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.Greater);
        }

        /// <summary>
        /// <![CDATA[>=]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator >=(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.GreaterOrEqual);
        }

        /// <summary>
        /// <![CDATA[<]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator <(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.Less);
        }

        /// <summary>
        /// <![CDATA[<=]]>
        /// </summary>
        /// <param name="leftField">左字段</param>
        /// <param name="rightField">右字段</param>
        /// <returns></returns>
        public static WhereClip operator <=(Field leftField, Field rightField)
        {
            return CreateWhereClip(leftField, rightField, QueryOperator.LessOrEqual);
        }

        /// <summary>
        /// <![CDATA[==]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator ==(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.Equal);
        }

        /// <summary>
        /// <![CDATA[==]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator ==(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.Equal);
        }

        /// <summary>
        /// <![CDATA[!=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator !=(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.NotEqual);
        }

        /// <summary>
        ///  <![CDATA[!=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator !=(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.NotEqual);
        }

        /// <summary>
        /// <![CDATA[>]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator >(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.Greater);
        }

        /// <summary>
        /// <![CDATA[>]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator >(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.Less);
        }

        /// <summary>
        /// <![CDATA[=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator >=(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.GreaterOrEqual);
        }

        /// <summary>
        /// <![CDATA[>=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator >=(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.LessOrEqual);
        }

        /// <summary>
        /// <![CDATA[<]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator <(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.Less);
        }

        /// <summary>
        /// <![CDATA[<]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator <(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.Greater);
        }

        /// <summary>
        /// <![CDATA[<=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator <=(Field field, object value)
        {
            return new WhereClip(field, value, QueryOperator.LessOrEqual);
        }

        /// <summary>
        /// <![CDATA[<=]]>
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public static WhereClip operator <=(object value, Field field)
        {
            return new WhereClip(field, value, QueryOperator.GreaterOrEqual);
        }
        #endregion


        /// <summary>
        /// +
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Field operator +(Field leftField, Field rightField)
        {
            return CreateField(leftField, rightField, QueryOperator.Add);
        }

        /// <summary>
        /// -
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Field operator -(Field leftField, Field rightField)
        {
            return CreateField(leftField, rightField, QueryOperator.Subtract);
        }

        /// <summary>
        /// *
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Field operator *(Field leftField, Field rightField)
        {
            return CreateField(leftField, rightField, QueryOperator.Multiply);
        }

        /// <summary>
        /// /
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Field operator /(Field leftField, Field rightField)
        {
            return CreateField(leftField, rightField, QueryOperator.Divide);
        }

        /// <summary>
        /// %
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Field operator %(Field leftField, Field rightField)
        {
            return CreateField(leftField, rightField, QueryOperator.Modulo);
        }


        /// <summary>
        /// +
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Expression operator +(Field leftField, object value)
        {
            return new Expression(leftField, value, QueryOperator.Add);
        }

        /// <summary>
        /// -
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Expression operator -(Field leftField, object value)
        {
            return new Expression(leftField, value, QueryOperator.Subtract);
        }


        /// <summary>
        /// *
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Expression operator *(Field leftField, object value)
        {
            return new Expression(leftField, value, QueryOperator.Multiply);
        }

        /// <summary>
        /// /
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Expression operator /(Field leftField, object value)
        {
            return new Expression(leftField, value, QueryOperator.Divide);
        }

        /// <summary>
        /// %
        /// </summary>
        /// <param name="leftField"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Expression operator %(Field leftField, object value)
        {
            return new Expression(leftField, value, QueryOperator.Modulo);
        }


        /// <summary>
        /// +
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Expression operator +(object value, Field rightField)
        {
            return new Expression(rightField, value, QueryOperator.Add, false);
        }

        /// <summary>
        /// -
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Expression operator -(object value, Field rightField)
        {
            return new Expression(rightField, value, QueryOperator.Subtract, false);
        }

        /// <summary>
        /// *
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Expression operator *(object value, Field rightField)
        {
            return new Expression(rightField, value, QueryOperator.Multiply, false);
        }

        /// <summary>
        /// /
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Expression operator /(object value, Field rightField)
        {
            return new Expression(rightField, value, QueryOperator.Divide, false);
        }

        /// <summary>
        /// %
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rightField"></param>
        /// <returns></returns>
        public static Expression operator %(object value, Field rightField)
        {
            return new Expression(rightField, value, QueryOperator.Modulo, false);
        }

        #endregion

        #endregion
    }
}
