2011-07-13 38 views
2

我正在處理一個數據庫,它只能支持我已經編寫代碼的數據類型。C#:聰明的助手類返回系統數據類型

我使用可用類型的列表創建了Enum參數。

public enum TableDataType 
{ 
    None=0, String=1, Integer=2, Character=3, Boolean=4, DateTime=5, Decimal=6 
} 

這工作,但我還是要處理要在和回來了我的數據結構:

TableDataType GetMyType(DataGridViewColumn col) { 
    TableDataType type; 
    if (col.ValueType == typeof(bool)) { 
    type = TableDataType.Boolean; 
    } else if (col.ValueType == typeof(char)) { 
    type = TableDataType.Character; 
    } else if (col.ValueType == typeof(DateTime)) { 
    type = TableDataType.DateTime; 
    } else if (col.ValueType == typeof(Decimal)) { 
    type = TableDataType.Decimal; 
    } else if (col.ValueType == typeof(Int32)) { 
    type = TableDataType.Integer; 
    } else if (col.ValueType == typeof(string)) { 
    type = TableDataType.String; 
    } else { 
    throw new ArgumentException(string.Format("Data Type of '{0}' is not supported.", col.ValueType)); 
    } 
    return type; 
} 

再有就是代碼走另一條路......

Type GetSystemType(TableDataType myType) { 
    Type sysType; 
    switch (myType) { 
    case TableDataType.Boolean: sysType = typeof(bool); break; 
    case TableDataType.Character: sysType = typeof(char); break; 
    case TableDataType.DateTime: sysType = typeof(DateTime); break; 
    case TableDataType.Integer: sysType = typeof(Int32); break; 
    case TableDataType.Decimal: sysType = typeof(Decimal); break; 
    case TableDataType.String: sysType = typeof(string); break; 
    default: throw new ArgumentOutOfRangeException(string.Format("Data Type '{0}' is not allowed.", cd.DataType)); 
    } 
    return sysType; 
} 

問題出在我的代碼中使用類似於這些例程的多個地方。如果我告訴DataGridViewColumn它被格式化爲Int32然後通過它Integer,我得到ArgumentException錯誤。

我正在尋找一個很好,快速的類包裝,巧妙地存儲值和可接受的數據類型的選擇範圍。

[編輯]解決方案,我想出了:

使用harpo的評論和Bas的解決方案所提供的信息,我創建了這個類:

public static class Enumerate { 

    private Enumerate() { 
    throw new NotSupportedException(); 
    } 

    public static SqlDbType ForSqlCe(System.Type item) { 
    return sqlDbCode(item); 
    } 

    public static SqlDbType ForSqlCe(TableDataType item) { 
    return sqlDbCode(item.GetType()); 
    } 

    static SqlDbType sqlDbCode(System.Type item) { 
    switch (Type.GetTypeCode(item)) { 
     case TypeCode.Boolean: return SqlDbType.Bit; 
     case TypeCode.Byte: 
     case TypeCode.Char: 
     case TypeCode.SByte: return SqlDbType.NChar; 
     case TypeCode.DateTime: return SqlDbType.DateTime; 
     case TypeCode.Decimal: 
     case TypeCode.Double: 
     case TypeCode.Single: return SqlDbType.Decimal; 
     case TypeCode.Int16: 
     case TypeCode.Int32: 
     case TypeCode.Int64: 
     case TypeCode.UInt16: 
     case TypeCode.UInt32: 
     case TypeCode.UInt64: return SqlDbType.Int; 
     case TypeCode.String: return SqlDbType.NVarChar; 
     case TypeCode.DBNull: 
     case TypeCode.Empty: 
     case TypeCode.Object: 
     default: throw new TypeAccessException(item + " unknown"); 
    } 
    } 

    public static TableDataType ForTableData(SqlDbType item) { 
    return tableDataCode(item.GetType()); 
    } 

    public static TableDataType ForTableData(System.Type item) { 
    return tableDataCode(item); 
    } 

    static TableDataType tableDataCode(System.Type item) { 
    switch (Type.GetTypeCode(item)) { 
     case TypeCode.Boolean: return TableDataType.Boolean; 
     case TypeCode.Byte: 
     case TypeCode.Char: 
     case TypeCode.SByte: return TableDataType.Character; 
     case TypeCode.DateTime: return TableDataType.DateTime; 
     case TypeCode.Decimal: 
     case TypeCode.Double: 
     case TypeCode.Single: return TableDataType.Decimal; 
     case TypeCode.Int16: 
     case TypeCode.Int32: 
     case TypeCode.Int64: 
     case TypeCode.UInt16: 
     case TypeCode.UInt32: 
     case TypeCode.UInt64: return TableDataType.Integer; 
     case TypeCode.String: return TableDataType.String; 
     case TypeCode.DBNull: 
     case TypeCode.Empty: 
     case TypeCode.Object: 
     default: throw new TypeAccessException(item + " unknown"); 
    } 
    } 

    public static Type ForWin32(string item) { 
    string text = item.Trim().ToLower(); 
    switch (text) { 
     case "boolean": 
     case "bool": 
     case "bit": return typeof(bool); 
     case "byte": 
     case "char": 
     case "sbyte": return typeof(char); 
     case "date": 
     case "datetime": 
     case "time": return typeof(DateTime); 
     case "decimal": 
     case "double": 
     case "numeric": 
     case "single": return typeof(Double); 
     case "int": 
     case "int16": 
     case "int32": 
     case "int64": 
     case "integer": 
     case "uint16": 
     case "uint32": 
     case "uint64": return typeof(Int32); 
     case "string": return typeof(string); 
     default: 
     throw new TypeAccessException(item + " unknown"); 
    } 
    } 

    public static Type ForWin32(SqlDbType item) { 
    return win32Code(item.GetType()); 
    } 

    public static Type ForWin32(TableDataType item) { 
    return win32Code(item.GetType()); 
    } 

    static Type win32Code(System.Type item) { 
    switch (Type.GetTypeCode(item)) { 
     case TypeCode.Boolean: return typeof(bool); 
     case TypeCode.Byte: 
     case TypeCode.Char: 
     case TypeCode.SByte: return typeof(char); 
     case TypeCode.DateTime: return typeof(DateTime); 
     case TypeCode.Decimal: 
     case TypeCode.Double: 
     case TypeCode.Single: return typeof(Decimal); 
     case TypeCode.Int16: 
     case TypeCode.Int32: 
     case TypeCode.Int64: 
     case TypeCode.UInt16: 
     case TypeCode.UInt32: 
     case TypeCode.UInt64: return typeof(Int32); 
     case TypeCode.String: return typeof(string); 
     case TypeCode.DBNull: 
     case TypeCode.Empty: 
     case TypeCode.Object: 
     default: throw new TypeAccessException(item + " unknown"); 
    } 
    } 

} 
+1

您可能想查看['System.TypeCode'](http://msdn.microsoft.com/zh-cn/library/system。 typecode.aspx)。我不知道這是否與Type.GetTypeCode和Convert.ChangeType一起會覆蓋你的需求,但它至少會用內置的替換你的自定義枚舉。 – harpo

+0

用於訪問你的數據庫的代碼是否有確定數據類型的方法?您可以使用常見的.Net數據適配器和讀取器來執行此操作。 –

+1

爲什麼不建立像Dictionary 這樣的字典? –

回答

4

如果你不想使用System.TypeCodeharpo建議,使用Type.GetType()

string assemblyQualifiedName = "System.{0}, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 

string typeString = myEnumValue.ToString(); 
Type type = Type.GetType(string.Format(assemblyQualifiedName, typeString)); 

另一種選擇是將映射存儲在字典中:

static class TypeResolver 
{ 
    static Dictionary<TableDataType, Type> typeLookup = new Dictionary<TableDataType, Type>(); 

    static TypeResolver() 
    { 
     typeLookup.Add(TableDataType.Integer, typeof(Int32)); 
     typeLookup.Add(TableDataType.String, typeof(String)); 
    } 

    public static Type Resolve(TableDataType tableType) 
    { 
     return typeLookup[tableType]; 
    } 
} 
+0

+1。我猜這需要第二個'Dictionary '來轉換回來。對? ...或者'typeLookup.Where(t => t == T)'? – jp2code

+0

+1這是我如何做到的。我希望有一個很好的方法來做到這一點。 –

+0

我會使用第二個字典來維護反向引用。這在使用時保留O(1)。 – Bas