zoukankan      html  css  js  c++  java
  • 轻量级表达式树解析框架Faller

    有话说

    之前我写了3篇关于表达式树解析的文章

    干货!表达式树解析"框架"(1)

    干货!表达式树解析"框架"(2)

    干货!表达式树解析"框架"(3) 

    这3篇文章更多的是说明一种方法,一种思路,而代码比较少

    在发出来之后也有些朋友互加了好友一起讨论

    在经过一些时间的修改和优化后,就有了现在这个框架

    目前这个框架实现了SqlServer和Oracle的解释

    其他数据库1来是不熟2来没时间3来我更希望大家可以使用这个框架自己动手实现一个数据库的解析,非常有意思

    特色

    1. 首先是这个框架的名字 : Faller 中译 伐木工,但我喜欢叫他 "砍树人",因为他把"表达式树"这颗大树砍成一片一片的小块然后转化成sql语句
    2. 轻量 : 不仅仅是代码轻量,重新实现对一个新的数据库支持也很轻量,只需要实现ISaw接口,或继承BaseSaw实现少量方法即可
      如 : 
      Where(u => u.Birthday.Day == 1);                   //EXTRACT(DAY FROM a.BIRTHDAY) = 1
      Where(u => u.Name.Trim() == "");                    //ltrim(rtrim(a.NAME)) = :auto_p0
      Where(u => string.IsNullOrEmpty(u.Name));      //a.NAME IS NULL OR a.NAME == ''
    3. 灵活 : 在轻量的基础上尽量做到了灵活,可以非常方便的解析各种C#的方法

    4. 对 DateTime.Now 的处理 : 
      如 :  Where(u => u.Birthday < DateTime.Now) //可以被解析为 BIRTHDAY < SYSDATE 或 BIRTHDAY < GETDATE() 
    5. 自由的 SqlExpr : 有时候 我们不得不使用Sql来表示某个数据库特有的数据
      如 :  Set<User>(() => new User{ ID = (SqlExpr)"seq_user.nextval"}) //解析后得到 ID = seq_user.nextval 
    6. 使用方便 : 可以非常方便的嵌入到现已有的项目中,主要根据自己项目的需求重新实现ISaw即可

    使用方式

    void Where(string expected, Expression<Func<User, bool>> expr)
    {
        var parse = Faller.Create(expr);     //通过LambdaExpression创建Faller对象
        var sql = parse.ToWhere(OracleSaw.Instance);//使用特定的ISaw来格式化Sql语句
        //parse.Parameters  //解析过程中产生的参数
        Assert.AreEqual(expected, sql);
    }

    项目结构

    • Faller : 解析框架主要功能类,不可重写,实现 IFaller 接口,主要方法有 public static IFaller Create(LambdaExpression expr)
    • ISaw : 定义一组方法,它支持自定义Sql语句的格式。Faller负责拆解 LambdaExpression ,然后把特定的对象交给ISaw处理返回sql语句 
    • SawDust : 解析结果。当一个方法在Faller中无法被解释时候,Faller会把方法所用到的对象和参数都构造成为SawDust 并交给ISaw处理,SawDust 由DustType Type和Object Value组成
    • DustType : 表示解释结果类型的枚举 ,它的值有 Undefined, Sql, Object, Number, Array, Boolean, DateTime, Binary, String
    • SqlExpr : Sql表达式,它只能由String强转获得; 它可以隐式转换为所有基础对象,但只能在表达式树中使用, 如
      Where<User>(u => (SqlExpr)"@@identity" == 5); //@@identity = 5

    对象定义

    // 轻量级表达式树解析器 接口 
    public interface IFaller
    {
        // 将表达式转为Where语句,不包含Where关键字
        //saw: 自定义输出Sql语句的格式的对象
        string ToWhere(ISaw saw);
        // 将表达式转为OrderBy语句,不包含OrderBy关键字
        //saw: 自定义输出Sql语句的格式的对象
        //asc: 正序或倒序标识
        string ToOrderBy(ISaw saw, bool asc);
        // 将表达式转为Update中Set语句,不包含Set关键字
        //saw: 自定义输出Sql语句的格式的对象
        string ToSets(ISaw saw);
        // 将表达式转为select语句中的列或列集合的Sql语句
        //saw: 自定义输出Sql语句的格式的对象
        string ToSelectColumns(ISaw saw);
        // 将表达式转为值或值集合的sql语句
        //saw: 自定义输出Sql语句的格式的对象
        string ToValues(ISaw saw);
        // 将表达式转为值或值集合的sql语句
        //saw: 自定义输出Sql语句的格式的对象
        string ToValues(ISaw saw, Func<string, string> replace);
        // 将表达式转为列集合和值集合2个sql语句,可用于拼装insert语句
        //saw: 自定义输出Sql语句的格式的对象
        KeyValuePair<string, string> ToColumnsAndValues(ISaw saw);
        // 转换Sql语句过程中产生的参数
        ICollection<DbParameter> Parameters { get; }
    }
    IFaller
        /// <summary> 定义一组方法,它支持自定义Sql语句的格式。
        /// </summary>
        public interface ISaw
        {
            /// <summary> 解释二元操作
            /// </summary>
            /// <param name="left">左元素</param>
            /// <param name="operator">二元操作符</param>
            /// <param name="right">右元素</param>
            string BinaryOperation(string left, BinaryOperator @operator, string right);
            /// <summary> 解释Contains操作
            /// </summary>
            /// <param name="not">是否为not</param>
            /// <param name="item">要在集合中查找的对象</param>
            /// <param name="array">要查找的集合</param>
            string ContainsOperation(bool not, string item, string[] array);
            /// <summary> 向参数集合中追加一个任意类型的参数,并返回参数名sql表达式
            /// </summary>
            /// <param name="obj">需要追加的参数值</param>
            /// <param name="parameters">参数集合</param>
            string AddObject(object obj, ICollection<DbParameter> parameters);
            /// <summary> 向参数集合中追加一个数字类型的参数,并返回参数名sql表达式
            /// </summary>
            /// <param name="number">需要追加的数字</param>
            /// <param name="parameters">参数集合</param>
            string AddNumber(IConvertible number, ICollection<DbParameter> parameters);
            /// <summary> 向参数集合中追加一个布尔类型的参数,并返回参数名sql表达式
            /// </summary>
            /// <param name="obj">需要追加的布尔值</param>
            /// <param name="parameters">参数集合</param>
            string AddBoolean(bool value, ICollection<DbParameter> parameters);
            /// <summary> 向参数集合中追加当前时间,并返回参数名sql表达式
            /// </summary>
            /// <param name="parameters">参数集合</param>
            string AddTimeNow(ICollection<DbParameter> parameters);
            /// <summary> 获取实体类型所映射的表名
            /// </summary>
            /// <param name="type">实体类型</param>
            /// <param name="alias">别名</param>
            string GetTable(Type type, string alias);
            /// <summary> 获取实体属性或字段所映射的列名
            /// </summary>
            /// <param name="table">表名或表别名</param>
            /// <param name="type">实体属性或字段</param>
            string GetColumn(string table, MemberInfo member);
            /// <summary> 获取列名和列别名组合后的sql表达式
            /// </summary>
            /// <param name="columnName">列名</param>
            /// <param name="alias">列别名</param>
            string GetColumn(string columnName, string alias);
            /// <summary> 将.NET中的方法解释为sql表达式
            /// </summary>
            /// <param name="method">需解释的方法</param>
            /// <param name="target">方法调用者</param>
            /// <param name="args">方法参数</param>
            /// <returns></returns>
            string ParseMethod(MethodInfo method, SawDust target, SawDust[] args);
        }
    ISaw
        /// <summary> 表达式树解析结果
        /// </summary>
        public struct SawDust
        {
            /// <summary> 结果类型
            /// </summary>
            public readonly DustType Type;
    
            /// <summary> 结果值
            /// </summary>
            public readonly Object Value;
    
            /// <summary> 无论结果类型 强制转换为Sql语句,DustType.Undefined抛出异常
            /// </summary>
            public string ToSql();
            
            /// <summary>  是否是非DustType.Sql和DustType.Undefined类型
            /// </summary>
            public bool IsObject { get;}
        }
    SawDust(不包含实现)
        /// <summary> 表达式解析结果类型
        /// </summary>
        [System.Serializable]
        public enum DustType
        {
            /// <summary> 未知
            /// </summary>
            Undefined = 0,
            /// <summary> sql语句
            /// </summary>
            Sql = 1,
            /// <summary> 未知类型
            /// </summary>
            Object = 2,
            /// <summary> 数字
            /// </summary>
            Number = 3,
            /// <summary> 数组
            /// </summary>
            Array = 4,
            /// <summary> 布尔值
            /// </summary>
            Boolean = 5,
            /// <summary> 时间
            /// </summary>
            DateTime = 6,
            /// <summary> 二进制
            /// </summary>
            Binary = 7,
            /// <summary> 字符串
            /// </summary>
            String = 8,
        }
    DustType
    /// <summary> Sql表达式
        /// </summary>
        public struct SqlExpr
        {
            public static explicit operator SqlExpr(string value);
    
            public static implicit operator bool(SqlExpr value);
            public static implicit operator byte(SqlExpr value);
            public static implicit operator char(SqlExpr value);
            public static implicit operator DateTime(SqlExpr value);
            public static implicit operator decimal(SqlExpr value);
            public static implicit operator double(SqlExpr value);
            public static implicit operator short(SqlExpr value);
            public static implicit operator int(SqlExpr value);
            public static implicit operator long(SqlExpr value);
            public static implicit operator sbyte(SqlExpr value);
            public static implicit operator float(SqlExpr value);
            public static implicit operator string(SqlExpr value);
            public static implicit operator ushort(SqlExpr value);
            public static implicit operator uint(SqlExpr value);
            public static implicit operator ulong(SqlExpr value);
            public static implicit operator Guid(SqlExpr value);
            public static implicit operator Byte[](SqlExpr value);
    
        }
    SqlExpr
        /// <summary> 支持自定义Sql语句格式基类。
        /// </summary>
        public abstract class BaseSaw : ISaw
        {
            /// <summary> 初始化并提供 DbProviderFactory
            /// </summary>
            /// <param name="factory"></param>
            protected BaseSaw(DbProviderFactory factory);
    
            /*
             * 接口已定义方法略...
             */
    
    
            /// <summary> 解释未知的方法
            /// </summary>
            /// <param name="method">需解释的方法</param>
            /// <param name="target">方法调用者</param>
            /// <param name="args">方法参数</param>
            protected virtual string ParseUnknownMethod(MethodInfo method, SawDust target, SawDust[] args);
            /// <summary> 获取新的数据库参数
            /// </summary>
            /// <param name="obj">参数值</param>
            protected virtual DbParameter GetDbParameter(object obj);
            /// <summary> 别名分隔符 默认 AS ,如 Table AS it
            /// </summary>
            protected virtual string AliasSeparator { get; }
    
            /// <summary> 解释按位运算 与,或,非
            /// </summary>
            /// <param name="val1">操作数1</param>
            /// <param name="val2">操作数2</param>
            /// <param name="opt">按位操作符</param>
            protected virtual string BitOperation(string val1, string val2, BitOperator opt);
            /// <summary> 解释取余运算
            /// </summary>
            /// <param name="val1">操作数1</param>
            /// <param name="val2">操作数2</param>
            /// <returns></returns>
            protected virtual string ModuloOperation(string val1, string val2);
            /// <summary> 解释幂运算
            /// </summary>
            /// <param name="val1">操作数1</param>
            /// <param name="val2">操作数2</param>
            /// <returns></returns>
            protected virtual string PowerOperation(string val1, string val2);
            /// <summary> 解释位移运算
            /// </summary>
            /// <param name="val1">操作数1</param>
            /// <param name="val2">操作数2</param>
            /// <param name="opt">按位操作符</param>
            protected virtual string ShiftOperation(string val1, string val2, ShiftOperator opt);
            /// <summary> 解释 String.Trim 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            /// <param name="arg">方法参数</param>
            protected virtual string StringTrim(string target, string arg);
            /// <summary> 解释 String.TrimEnd 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            /// <param name="arg">方法参数</param>
            protected virtual string StringTrimEnd(string target, string arg);
            /// <summary> 解释 String.TrimStart 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            /// <param name="arg">方法参数</param>
            protected virtual string StringTrimStart(string target, string arg);
            /// <summary> 解释 String.IsNullOrEmpty 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            protected virtual string StringIsNullOrEmpty(string target);
            /// <summary> 解释 String.IsNullOrWhiteSpace 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            protected virtual string StringIsNullOrWhiteSpace(string target);
            /// <summary> 解释 String.Length 方法
            /// </summary>
            /// <param name="target">方法调用者</param>
            protected virtual string StringLength(string target);
            /// <summary> 解释 Object.ToString 方法
            /// </summary>
            /// <param name="type">调用者类型</param>
            /// <param name="target">方法调用者</param>
            /// <param name="format">格式化参数</param>
            protected virtual string ObjectToString(DustType type, string target, string format);
            /// <summary> 解释 DateTime 中的数据
            /// </summary>
            /// <param name="datetime">方法调用者</param>
            protected virtual string DateTimeToField(string datetime, DateTimeField field);
            /// <summary> 解释各种 Number.Parse 方法
            /// </summary>
            /// <param name="target">string对象</param>
            protected virtual string SrtingToNumber(string target);
    
            #region abstract
    
            /// <summary> 返回实体类型所映射的表名
            /// </summary>
            /// <param name="type">实体类型</param>
            protected abstract string TableName(Type type);
            /// <summary> 返回实体属性或字段所映射的列名
            /// </summary>
            /// <param name="member">实体属性或字段</param>
            protected abstract string ColumnName(MemberInfo member);
    
            /// <summary> 参数的前缀符号,如SqlServer中的@,Oracle中的:
            /// </summary>
            protected abstract string ParameterPreFix { get; }
            /// <summary> 在数据库中表示当前时间的表达式,如SqlServer中的getdate,Oracle中的SYSDATE
            /// </summary>
            protected abstract string TimeNow { get; }
    
            /// <summary> 解释Like操作
            /// </summary>
            /// <param name="val1">操作数1</param>
            /// <param name="val2">操作数2</param>
            /// <param name="opt">按位操作符</param>
            protected abstract string LikeOperation(string val1, string val2, LikeOperator opt);
    
            #endregion
        }
    BaseSaw(不包含实现)
        /// <summary> 二元操作符枚举
        /// </summary>
        [Serializable]
        public enum BinaryOperator
        {
            /// <summary>/// </summary>
            Add,
            /// <summary>/// </summary>
            Subtract,
            /// <summary>/// </summary>
            Divide,
            /// <summary> 取余
            /// </summary>
            Modulo,
            /// <summary>/// </summary>
            Multiply,
            /// <summary> 幂运算
            /// </summary>
            Power,
            /// <summary> 位移运算 a &lt;&lt; b
            /// </summary>
            LeftShift,
            /// <summary> 位移运算 a &gt;&gt; b
            /// </summary>
            RightShift,
            /// <summary> 与 a &amp;&amp; b 或 a AND b
            /// </summary>
            And,
            /// <summary> 或 a || b 或 a OR b
            /// </summary>
            Or,
            /// <summary> 等于 a == b
            /// </summary>
            Equal,
            /// <summary> 不等于 a != b 或 a <> b
            /// </summary>
            NotEqual,
            /// <summary> 大于 a &gt; b
            /// </summary>
            GreaterThan,
            /// <summary> 大于等于 a &gt;= b
            /// </summary>
            GreaterThanOrEqual,
            /// <summary> 小于 a &lt; b
            /// </summary>
            LessThan,
            /// <summary> 小于等于 a &lt;= b
            /// </summary>
            LessThanOrEqual,
            /// <summary> LIKE操作 a LIKE %b%
            /// </summary>    
            Contains,         
            /// <summary> LIKE操作 a LIKE b%
            /// </summary>    
            StartWith,        
            /// <summary> LIKE操作 a LIKE %b
            /// </summary>    
            EndWith,          
            /// <summary> LIKE操作 a NOT LIKE %b%
            /// </summary>    
            NotContains,      
            /// <summary> LIKE操作 a NOT LIKE b%
            /// </summary>    
            NotStartWith,     
            /// <summary> LIKE操作 a NOT LIKE %b
            /// </summary>
            NotEndWith,
            /// <summary> 位运算 如 a &amp; b
            /// </summary>
            BitAnd,
            /// <summary> 位运算 如 a | b
            /// </summary>
            BitOr,
            /// <summary> 位运算 如 a ^ b
            /// </summary>
            BitXor,
        }
    
        /// <summary> 按位操作符枚举
        /// </summary>
        [Serializable]
        public enum BitOperator
        {
            /// <summary> 位运算 如 a &amp; b
            /// </summary>
            And,
            /// <summary> 位运算 如 a | b
            /// </summary>
            Or,
            /// <summary> 位运算 如 a ^ b
            /// </summary>
            Xor,
        }
    
    
        /// <summary> Like操作符枚举
        /// </summary>
        [Serializable]
        public enum LikeOperator
        {
            /// <summary> LIKE操作 a LIKE %b%
            /// </summary>    
            Contains,
            /// <summary> LIKE操作 a LIKE b%
            /// </summary>    
            StartWith,
            /// <summary> LIKE操作 a LIKE %b
            /// </summary>    
            EndWith,
            /// <summary> LIKE操作 a NOT LIKE %b%
            /// </summary>    
            NotContains,
            /// <summary> LIKE操作 a NOT LIKE b%
            /// </summary>    
            NotStartWith,
            /// <summary> LIKE操作 a NOT LIKE %b
            /// </summary>
            NotEndWith,
        }
    
        /// <summary> 位移操作符枚举
        /// </summary>
        [Serializable]
        public enum ShiftOperator
        {         
            /// <summary> 位移运算 a &lt;&lt; b
            /// </summary>
            Left,
            /// <summary> 位移运算 a &gt;&gt; b
            /// </summary>
            Right,
        }
    
        /// <summary> 时间字段
        /// </summary>
        [Serializable]
        public enum DateTimeField
        {
            /// <summary>/// </summary>
            Year,
            /// <summary>/// </summary>
            Month,
            /// <summary>/// </summary>
            Day,
            /// <summary>/// </summary>
            Hour,
            /// <summary>/// </summary>
            Minute,
            /// <summary>/// </summary>
            Second,
            /// <summary> 星期
            /// </summary>
            Week,
        }
    其他枚举

    再来一个已实现的MsSqlSaw

        public class MsSqlSaw : BaseSaw
        {
            public static MsSqlSaw Instance = new MsSqlSaw();
    
            private MsSqlSaw() : base(System.Data.SqlClient.SqlClientFactory.Instance) { }
    
            private static HashSet<string> KeyWords = InitKeyWords();
    
            private static HashSet<string> InitKeyWords()
            {
                return new HashSet<string>("ABSOLUTE,ACTION,ADA,ADD,ADMIN,AFTER,AGGREGATE,ALIAS,ALL,ALLOCATE,ALTER,AND,ANY,ARE,ARRAY,AS,ASC,ASSERTION,AT,AUTHORIZATION,AVG,BACKUP,BEFORE,BEGIN,BETWEEN,BINARY,BIT,BIT_LENGTH,BLOB,BOOLEAN,BOTH,BREADTH,BREAK,BROWSE,BULK,BY,CALL,CASCADE,CASCADED,CASE,CAST,CATALOG,CHAR,CHARACTER,CHARACTER_LENGTH,CHAR_LENGTH,CHECK,CHECKPOINT,CLASS,CLOB,CLOSE,CLUSTERED,COALESCE,COLLATE,COLLATION,COLUMN,COMMIT,COMPLETION,COMPUTE,CONNECT,CONNECTION,CONSTRAINT,CONSTRAINTS,CONSTRUCTOR,CONTAINS,CONTAINSTABLE,CONTINUE,CONVERT,CORRESPONDING,COUNT,CREATE,CROSS,CUBE,CURRENT,CURRENT_DATE,CURRENT_PATH,CURRENT_ROLE,CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,CURSOR,CYCLE,DATA,DATABASE,DATE,DAY,DBCC,DEALLOCATE,DEC,DECIMAL,DECLARE,DEFAULT,DEFERRABLE,DEFERRED,DELETE,DENY,DEPTH,DEREF,DESC,DESCRIBE,DESCRIPTOR,DESTROY,DESTRUCTOR,DETERMINISTIC,DIAGNOSTICS,DICTIONARY,DISCONNECT,DISK,DISTINCT,DISTRIBUTED,DOMAIN,DOUBLE,DROP,DUMMY,DUMP,DYNAMIC,EACH,ELSE,END,END-EXEC,EQUALS,ERRLVL,ESCAPE,EVERY,EXCEPT,EXCEPTION,EXEC,EXECUTE,EXISTS,EXIT,EXTERNAL,EXTRACT,FALSE,FETCH,FILE,FILLFACTOR,FIRST,FLASE,FLOAT,FOR,FOREIGN,FORTRAN,FOUND,FREE,FREETEXT,FREETEXTTABLE,FROM,FULL,FUNCTION,GENERAL,GET,GLOBAL,GO,GOTO,GRANT,GROUP,GROUPING,HAVING,HOLDLOCK,HOST,HOUR,IDENTITY,IDENTITYCOL,IDENTITY_INSERT,IF,IGNORE,IMMEDIATE,IN,INCLUDE,INDEX,INDICATOR,INITIALIZE,INITIALLY,INNER,INOUT,INPUT,INSENSITIVE,INSERT,INT,INTEGER,INTERSECT,INTERVAL,INTO,IS,ISOLATION,ITERATE,JOIN,KEY,KILL,LANGUAGE,LARGE,LAST,LATERAL,LEADING,LEFT,LESS,LEVEL,LIKE,LIMIT,LINENO,LOAD,LOCAL,LOCALTIME,LOCALTIMESTAMP,LOCATOR,LOWER,MAP,MATCH,MAX,MIN,MINUTE,MODIFIES,MODIFY,MODULE,MONTH,NAMES,NATIONAL,NATURAL,NCHAR,NCLOB,NEW,NEXT,NO,NOCHECK,NONCLUSTERED,NONE,NOT,NULL,NULLIF,NUMERIC,OBJECT,OCTET_LENGTH,OF,OFF,OFFSETS,OLD,ON,ONLY,OPEN,OPENDATASOURCE,OPENQUERY,OPENROWSET,OPENXML,OPERATION,OPTION,OR,ORDER,ORDINALITY,OUT,OUTER,OUTPUT,OVER,OVERLAPS,PAD,PARAMETER,PARAMETERS,PARTIAL,PASCAL,PATH,PERCENT,PLAN,POSITION,POSTFIX,PRECISION,PREFIX,PREORDER,PREPARE,PRESERVE,PRIMARY,PRINT,PRIOR,PRIVILEGES,PROC,PROCEDURE,PUBLIC,RAISERROR,READ,READS,READTEXT,REAL,RECONFIGURE,RECURSIVE,REF,REFERENCES,REFERENCING,RELATIVE,REPLICATION,RESTORE,RESTRICT,RESULT,RETURN,RETURNS,REVOKE,RIGHT,ROLE,ROLLBACK,ROLLUP,ROUTINE,ROW,ROWCOUNT,ROWGUIDCOL,ROWS,RULE,SAVE,SAVEPOINT,SCHEMA,SCOPE,SCROLL,SEARCH,SECOND,SECTION,SELECT,SEQUENCE,SESSION,SESSION_USER,SET,SETS,SETUSER,SHUTDOWN,SIZE,SMALLINT,SOME,SPACE,SPECIFIC,SPECIFICTYPE,SQL,SQLCA,SQLCODE,SQLERROR,SQLEXCEPTION,SQLSTATE,SQLWARNING,START,STATE,STATEMENT,STATIC,STATISTICS,STRUCTURE,SUBSTRING,SUM,SYSTEM_USER,TABLE,TEMPORARY,TERMINATE,TEXTSIZE,THAN,THEN,TIME,TIMESTAMP,TIMEZONE_HOUR,TIMEZONE_MINUTE,TO,TOP,TRAILING,TRAN,TRANSACTION,TRANSLATE,TRANSLATION,TREAT,TRIGGER,TRIM,TRUE,TRUNCATE,TSEQUAL,UNDER,UNION,UNIQUE,UNKNOWN,UNNEST,UPDATE,UPDATETEXT,UPPER,USAGE,USE,USER,USING,VALUE,VALUES,VARCHAR,VARIABLE,VARYING,VIEW,WAITFOR,WHEN,WHENEVER,WHERE,WHILE,WITH,WITHOUT,WORK,WRITE,WRITETEXT,YEAR,ZONE".Split(','), StringComparer.OrdinalIgnoreCase);
            }
    
            protected override string TableName(Type type)
            {
                var name = type.Name;
                if (KeyWords.Contains(name))
                {
                    return string.Concat("[", name, "]");
                }
                return name;
            }
    
            protected override string ColumnName(MemberInfo member)
            {
                var name = member.Name;
                if (KeyWords.Contains(name))
                {
                    return string.Concat("[", name, "]");
                }
                return name;
            }
    
            protected override string ParameterPreFix { get { return "@"; } }
    
            protected override string TimeNow { get { return "GETDATE()"; } }
    
            protected override string LikeOperation(string val1, string val2, LikeOperator opt)
            {
                switch (opt)
                {
                    case LikeOperator.Contains:
                        return string.Concat(val1, " LIKE '%' + ", val2, " + '%'");
                    case LikeOperator.StartWith:
                        return string.Concat(val1, " LIKE ", val2, " + '%'");
                    case LikeOperator.EndWith:
                        return string.Concat(val1, " LIKE '%' + ", val2);
                    case LikeOperator.NotContains:
                        return string.Concat(val1, " NOT LIKE '%' + ", val2, " + '%'");
                    case LikeOperator.NotStartWith:
                        return string.Concat(val1, " NOT LIKE ", val2, " + '%'");
                    case LikeOperator.NotEndWith:
                        return string.Concat(val1, " NOT LIKE '%' + ", val2);
                    default:
                        throw new ArgumentOutOfRangeException("opt");
                }
            }
    
            protected override string BitOperation(string val1, string val2, BitOperator opt)
            {
                switch (opt)
                {
                    case BitOperator.And:
                        return string.Concat(val1, " & ", val2);
                    case BitOperator.Or:
                        return string.Concat(val1, " | ", val2);
                    case BitOperator.Xor:
                        return string.Concat(val1, " ^ ", val2);
                    default:
                        throw new ArgumentOutOfRangeException("opt");
                }
            }
    
            protected override string StringTrim(string target, string arg)
            {
                if (arg != null)
                {
                    throw new NotSupportedException("不支持参数");
                }
                return string.Concat("LTRIM(RTRIM(", target, "))");
            }
    
            protected override string StringTrimEnd(string target, string arg)
            {
                if (arg != null)
                {
                    throw new NotSupportedException("不支持参数");
                }
                return string.Concat("RTRIM(", target, ")");
            }
    
            protected override string StringTrimStart(string target, string arg)
            {
                if (arg != null)
                {
                    throw new NotSupportedException("不支持参数");
                }
                return string.Concat("LTRIM(", target, ")");
            }
    
            protected override string StringLength(string target)
            {
                return string.Concat("LEN(", target, ")");
            }
    
            protected override string SrtingToNumber(string target)
            {
                return string.Concat("CAST(", target, " as decimal)");
            }
    
            protected override string ObjectToString(DustType type, string target, string format)
            {
                switch (type)
                {
                    case DustType.Undefined:
                        break;
                    case DustType.Sql:
                        break;
                    case DustType.Object:
                        break;
                    case DustType.Number:
                        if (format != null)
                        {
                            throw new NotSupportedException("不支持参数");
                        }
                        return string.Concat("CAST(", target, " as NVARCHAR)");
                    case DustType.Array:
                        break;
                    case DustType.Boolean:
                        break;
                    case DustType.DateTime:
                        switch (format)
                        {
                            case "'HH:mm'":
                                return string.Concat("CONVERT(VARCHAR(5),", target, ",114)");
                            case "'HH:mm:ss'":
                                return string.Concat("CONVERT(VARCHAR(8),", target, ",114)");
                            case "'HH:mm:ss.fff'":
                                return string.Concat("CONVERT(VARCHAR(12),", target, ",114)");
                            case "'yyyy-MM-dd'":
                                return string.Concat("CONVERT(VARCHAR(10),", target, ",21)");
                            case "'yyyy-MM-dd HH:mm'":
                                return string.Concat("CONVERT(VARCHAR(16),", target, ",21)");
                            case "'yyyy-MM-dd HH:mm:ss'":
                                return string.Concat("CONVERT(VARCHAR(19),", target, ",21)");
                            case "'yyyy-MM-dd HH:mm:ss.fff'":
                                return string.Concat("CONVERT(VARCHAR(23),", target, ",21)");
                            case "'yy/MM/dd'":
                                return string.Concat("CONVERT(VARCHAR(8),", target, ",111)");
                            case "'yyMMdd'":
                                return string.Concat("CONVERT(VARCHAR(6),", target, ",112)");
                            default:
                                break;
                        }
                        throw new NotSupportedException("不支持当前参数");
                    case DustType.Binary:
                        break;
                    case DustType.String:
                        break;
                    default:
                        break;
                }
                return base.ObjectToString(type, target, format);
            }
    
            protected override string DateTimeToField(string datetime, DateTimeField field)
            {
                switch (field)
                {
                    case DateTimeField.Year:
                        return string.Concat("DATEPART(YYYY, ", datetime, ")");
                    case DateTimeField.Month:
                        return string.Concat("DATEPART(mm, ", datetime, ")");
                    case DateTimeField.Day:
                        return string.Concat("DATEPART(dd, ", datetime, ")");
                    case DateTimeField.Hour:
                        return string.Concat("DATEPART(hh, ", datetime, ")");
                    case DateTimeField.Minute:
                        return string.Concat("DATEPART(mi, ", datetime, ")");
                    case DateTimeField.Second:
                        return string.Concat("DATEPART(ss, ", datetime, ")");
                    case DateTimeField.Week:
                        return string.Concat("(DATEPART(w, ", datetime, ") - 1)");
                    default:
                        throw new ArgumentOutOfRangeException("field");
                }
            }
        }
    MsSqlSaw

    部分解释结果展示(以OracleSaw为例)

    下载地址

    https://code.csdn.net/jy02305022/blqw-faller

    广告

    对C#感兴趣的朋友可以来群里讨论,入群方式见签名

  • 相关阅读:
    各种插件
    如何在C#中选择正确的集合 转
    转载 hashtable和dictionary的区别
    堆和栈的区别 转载
    数据结构王道错题集2019版(上>一>四章)
    mongoDB连接数据库
    linuix没有网络
    rand函数
    mongodb学习(入门。。。。。)
    先随便写
  • 原文地址:https://www.cnblogs.com/blqw/p/Faller.html
Copyright © 2011-2022 走看看