主流資料庫欄位型別轉.Net型別的方法

jimmy1357發表於2014-03-08

最近在閱讀一些開源的程式碼,發現其中有些方法總結的很全面,至少在我做同樣的事情時候,需要抓破腦袋想活著google,現在看到了這個關於主流資料庫欄位型別轉.Net型別的方法,故收藏之,也順便分享給那些能看到這篇文章的同學。具體程式碼如下 :

/// <summary>
        /// Default IDataType implementation (see IDataType for details)
        /// </summary>
        public class DataType : IDataType
        {
            public virtual string SqlType { get; set; }
            public virtual string ManagedType { get; set; }
            public virtual bool Nullable { get; set; }
            public virtual long? Length { get; set; }
            public virtual int? Precision { get; set; }
            public virtual int? Scale { get; set; }
            public virtual bool? Unsigned { get; set; }
            public string FullType { get; set; }
        }

        protected virtual Type MapDbType(string columnName, IDataType dataType)
        {
            if (dataType == null)
                throw new ArgumentNullException("dataType");
            if (dataType.ManagedType != null)
                return Type.GetType(dataType.ManagedType, true);

            string dataTypeL = dataType.SqlType.ToLowerInvariant();

            if (columnName != null && columnName.ToLower().Contains("guid"))
            {
                bool correctTypeAndLen =
                    ((dataTypeL == "char" || dataTypeL == "varchar") && dataType.Length == 36)
                    || ((dataTypeL == "binary") && dataType.Length == 16);

                if (correctTypeAndLen)
                {
                    Console.WriteLine("experimental support for guid--");
                    return typeof(Guid);
                }
            }

            switch (dataTypeL)
            {
            // string
            case "c":
            case "char":
            case "character":
            case "character varying":
            case "inet":
            case "long":
            case "longtext":
            case "long varchar":
            case "mediumtext":
            case "nchar":
            case "ntext":
            case "nvarchar":
            case "nvarchar2":
            case "string":
            case "text":
            case "varchar":
            case "varchar2":
            case "clob":    // oracle type
            case "nclob":   // oracle type
            case "rowid":   // oracle type
            case "urowid":  // oracle type
            case "tinytext": // mysql type
                return typeof(String);

            // bool
            case "bit":
            case "bool":
            case "boolean":
                return typeof(Boolean);

            // int8
            case "tinyint":
                if (dataType.Length == 1)
                    return typeof(Boolean);
                // tinyint is supposed to be signed
                // but we can have explicit sign
                if (dataType.Unsigned ?? false)
                    return typeof(Byte);
                // default case, unsigned
                return typeof(SByte);

            // int16
            case "short":
            case "smallint":
                if (dataType.Unsigned ?? false)
                    return typeof(UInt16);
                return typeof(Int16);

            // int32
            case "int":
            case "integer":
            case "mediumint":
                if (dataType.Unsigned ?? false)
                    return typeof(UInt32);
                return typeof(Int32);

            // int64
            case "bigint":
                return typeof(Int64);

            // single
            case "float":
            case "float4":
            case "real":
            case "binary_float":   // oracle type
            case "unsigned float": // mysql type
            case "float unsigned": // mysql type
                return typeof(Single);

            // double
            case "double":
            case "double precision":
            case "binary_double":  // oracle type
            case "unsigned double":// mysql type
            case "double unsigned":// mysql type
                return typeof(Double);

            // decimal
            case "decimal":
            case "money":
            case "numeric":
                return typeof(Decimal);
            case "number": // special oracle type
                if (dataType.Precision.HasValue && (dataType.Scale ?? 0) == 0)
                {
                    if (dataType.Precision.Value == 1)
                        return typeof(Boolean);
                    if (dataType.Precision.Value <= 4)
                        return typeof(Int16);
                    if (dataType.Precision.Value <= 9)
                        return typeof(Int32);
                    if (dataType.Precision.Value <= 19)
                        return typeof(Int64);
                }
                return typeof(Decimal);

            // time interval
            case "interval":
                return typeof(TimeSpan);

            //enum
            case "enum":
            case "set":
                return MapEnumDbType(dataType);

            // date
            case "date":
            case "datetime":
            case "ingresdate":
            case "timestamp":
            case "timestamp without time zone":
            case "timestamp with time zone":
            case "time":
            case "time without time zone": //reported by twain_bu...@msn.com,
            case "time with time zone":
                return typeof(DateTime);

            // byte[]
            case "binary":
            case "blob":
            case "bytea":
            case "byte varying":
            case "image":
            case "longblob":
            case "long byte":
            case "oid":
            case "sytea":
            case "mediumblob":
            case "tinyblob":
            case "raw":       // oracle type
            case "long raw":  // oracle type
            case "varbinary":
                return typeof(Byte[]);

            // PostgreSQL, for example has an uuid type that can be mapped as a Guid
            case "uuid":
                return typeof(Guid);

            case "void":
                return null;

            // if we fall to this case, we must handle the type
            default:
                throw new ArgumentException(
                    string.Format("Don't know how to convert the SQL type '{0}' into a managed type.", dataTypeL),
                    "dataType");
            }
        }


相關文章