2013-08-13 21 views
5

Jeśli podano ciąg znaków, który zawiera typ danych SQL Server/T-SQL, jaki jest najłatwiejszy sposób oceny łańcucha na typ .Net?Biorąc pod uwagę typ T-SQL jako ciąg, jaki jest najłatwiejszy sposób oceny go do typu .Net?

Na przykład, jeśli masz ciąg zawierający "nvarchar", wynik zwracany przez metodę konwersji powinien być typu System.String. Jeśli mam ciąg znaków zawierający "int", wynikiem powinien być obiekt typu System.Int32.

Mogę łatwo napisać funkcję, która pobiera ciąg danych SQL i wysyła ciąg przez instrukcję switch/case, która zwraca obiekt typu .Net Type. Nie byłem jednak pewien, czy w strukturze .Net została ukryta funkcja, którą przeoczyłem, już to robi.

Jaki jest najłatwiejszy/poprawny sposób na typ danych SQL Server na typ danych .Net?

dodatkowy kontekst

w moim przypadku, ja rzeczywiście mają procedurę przechowywaną, która zwraca niektóre meta-informacje na temat danych. W szczególności zwracane jest pole ciągu zawierające wartość typu sql, która może być dowolnym typem sql, który był dostępny w SQL Server 2005.

Moja procedura składowana ma potencjał zwracania dowolnego typu sql - int, smallint , datetime, binary, itp. Muszę wziąć ten typ danych i przekonwertować go na obiekt .Net Type.

Poniższy komentarz Matthew zawiera wszystkie niezbędne informacje na temat mapowania, prosto z dokumentacji firmy Microsoft, ale znowu zastanawiałem się, czy coś jest zintegrowane z przestrzeniami nazw System.Data lub System.Data.SqlClient.

+4

SQL-CLR typ mapowania: http://msdn.microsoft.com/en-us/library/bb386947.aspx – Matthew

+0

Jeśli ciąg zawiera jakieś dane z SQL następnie dane są obecnie ciągiem. Może mógłby pomóc jakiś kontekst. – Nick

+0

Tak jak powiedział @Matthew, potrzebne jest mapowanie typów SQL-CLR. –

Odpowiedz

2

Nie ma nic odsłoniętego, co znam. Głęboko w kodzie System.Data.SqlClient jest ta funkcja, która służy do określenia mapowania typu:

internal Type GetTypeFromStorageType(bool isSqlType) 
{ 
    if (isSqlType) 
    { 
     switch (this._type) 
     { 
      case StorageType.Empty: 
       return null; 

      case StorageType.Boolean: 
       return typeof(SqlBoolean); 

      case StorageType.Byte: 
       return typeof(SqlByte); 

      case StorageType.DateTime: 
       return typeof(SqlDateTime); 

      case StorageType.Decimal: 
       return typeof(SqlDecimal); 

      case StorageType.Double: 
       return typeof(SqlDouble); 

      case StorageType.Int16: 
       return typeof(SqlInt16); 

      case StorageType.Int32: 
       return typeof(SqlInt32); 

      case StorageType.Int64: 
       return typeof(SqlInt64); 

      case StorageType.Money: 
       return typeof(SqlMoney); 

      case StorageType.Single: 
       return typeof(SqlSingle); 

      case StorageType.String: 
       return typeof(SqlString); 

      case StorageType.SqlBinary: 
       return typeof(object); 

      case StorageType.SqlCachedBuffer: 
       return typeof(SqlString); 

      case StorageType.SqlGuid: 
       return typeof(object); 

      case StorageType.SqlXml: 
       return typeof(SqlXml); 
     } 
    } 
    else 
    { 
     switch (this._type) 
     { 
      case StorageType.Empty: 
       return null; 

      case StorageType.Boolean: 
       return typeof(bool); 

      case StorageType.Byte: 
       return typeof(byte); 

      case StorageType.DateTime: 
       return typeof(DateTime); 

      case StorageType.Decimal: 
       return typeof(decimal); 

      case StorageType.Double: 
       return typeof(double); 

      case StorageType.Int16: 
       return typeof(short); 

      case StorageType.Int32: 
       return typeof(int); 

      case StorageType.Int64: 
       return typeof(long); 

      case StorageType.Money: 
       return typeof(decimal); 

      case StorageType.Single: 
       return typeof(float); 

      case StorageType.String: 
       return typeof(string); 

      case StorageType.SqlBinary: 
       return typeof(byte[]); 

      case StorageType.SqlCachedBuffer: 
       return typeof(string); 

      case StorageType.SqlGuid: 
       return typeof(Guid); 

      case StorageType.SqlXml: 
       return typeof(string); 
     } 
    } 
    return null; 
} 
+0

Tak, chodzi o to, co podejrzewałem. Nie boję się długich zdań i w rzeczywistości może to być dla mnie bardziej korzystne, ponieważ mogę przesłonić niektóre typy.Mimo to wolę zintegrowane rozwiązanie, o ile takie istnieje, ponieważ łatwo jest "przegapić" coś z tego typu operacjami, co może mieć tragiczne konsekwencje podczas pracy z krytycznymi danymi. Otrzymujesz +1 i za kilka dni, jeśli nie ma lepszej odpowiedzi, prawdopodobnie znak odpowiedzi. – RLH

0

Wypróbuj funkcję poniżej. Jestem pewien, że możesz dostosować go do swoich potrzeb. Jeśli coś brakowało dostaniesz wyjątek:

public static Type SqlTypeToType(string type) 
    { 
     string[] tokens = type.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries); 
     string typeFamily = tokens[0].ToLowerInvariant(); 
     string size = tokens.Length > 1 ? tokens[1] : string.Empty; 

     switch (typeFamily) 
     { 
      case "bigint": 
       return typeof(long); 
      case "binary": 
       return size == "1" ? typeof(byte) : typeof(byte[]); 
      case "bit": 
       return typeof(bool); 
      case "char": 
       return size == "1" ? typeof(char) : typeof(string); 
      case "datetime": 
       return typeof(DateTime); 
      case "decimal": 
       return typeof(decimal); 
      case "float": 
       return typeof(double); 
      case "image": 
       return typeof(byte[]); 
      case "int": 
       return typeof(int); 
      case "money": 
       return typeof(double); 
      case "nchar": 
       return size == "1" ? typeof(char) : typeof(string); 
      case "ntext": 
       return typeof(string); 
      case "nvarchar": 
       return typeof(string); 
      case "real": 
       return typeof(float); 
      case "uniqueidentifier": 
       return typeof(Guid); 
      case "smalldatetime": 
       return typeof(DateTime); 
      case "smallint": 
       return typeof(short); 
      case "smallmoney": 
       return typeof(float); 
      case "sql_variant": 
       return typeof(string); 
      case "text": 
       return typeof(string); 
      case "timestamp": 
       return typeof(TimeSpan); 
      case "tinyint": 
       return typeof(byte); 
      case "varbinary": 
       return typeof(byte[]); 
      case "varchar": 
       return typeof(string); 
      case "variant": 
       return typeof(string); 
      case "xml": 
       return typeof(string); 
      default: 
       throw new ArgumentException(string.Format("There is no .Net type specified for mapping T-SQL type '{0}'.", typeFamily)); 
     } 
    } 
+0

Yikes, nie używaj tego. Mapowanie pieniędzy i smallmoney na podwojenie? To bardzo niebezpieczne. – test

+0

@parkparkes, jaka jest Twoja sugestia? dziesiętny? –

Powiązane problemy