Desafortunadamente, hasta donde sé, esta asignación no está expuesta en el código dentro de .NET Framework. Antes busqué en el origen de referencia de .NET Framework y descubrí que dentro del código .NET hay muchas sentencias de conmutación largas por tipo, como las que intenta evitar, pero ninguna de ellas parece estar expuesto externamente
Si realmente desea hacer un mapa de SqlTypes al tipo de .NET más parecido, creo que su mejor opción es simplemente convertir la tabla de asignación in the MSDN docs en el código. Tenga en cuenta que la tabla en MSDN tiene (al menos) dos errores: # 1: no hay tipo .NET llamado "DateTime2" (utilicé DateTime) y tampoco hay ningún tipo llamado "Xml" (utilicé SqlXml).
De todos modos, aquí está el mapeo que he estado usando-- usando un diccionario en lugar de un interruptor para facilitar el acceso sin un método diferente.
public static Dictionary<SqlDbType, Type> TypeMap = new Dictionary<SqlDbType, Type>
{
{ SqlDbType.BigInt, typeof(Int64) },
{ SqlDbType.Binary, typeof(Byte[]) },
{ SqlDbType.Bit, typeof(Boolean) },
{ SqlDbType.Char, typeof(String) },
{ SqlDbType.Date, typeof(DateTime) },
{ SqlDbType.DateTime, typeof(DateTime) },
{ SqlDbType.DateTime2, typeof(DateTime) },
{ SqlDbType.DateTimeOffset, typeof(DateTimeOffset) },
{ SqlDbType.Decimal, typeof(Decimal) },
{ SqlDbType.Float, typeof(Double) },
{ SqlDbType.Int, typeof(Int32) },
{ SqlDbType.Money, typeof(Decimal) },
{ SqlDbType.NChar, typeof(String) },
{ SqlDbType.NText, typeof(String) },
{ SqlDbType.NVarChar, typeof(String) },
{ SqlDbType.Real, typeof(Single) },
{ SqlDbType.SmallInt, typeof(Int16) },
{ SqlDbType.SmallMoney, typeof(Decimal) },
{ SqlDbType.Structured, typeof(Object) }, // might not be best mapping...
{ SqlDbType.Text, typeof(String) },
{ SqlDbType.Time, typeof(TimeSpan) },
{ SqlDbType.Timestamp, typeof(Byte[]) },
{ SqlDbType.TinyInt, typeof(Byte) },
{ SqlDbType.Udt, typeof(Object) }, // might not be best mapping...
{ SqlDbType.UniqueIdentifier, typeof(Guid) },
{ SqlDbType.VarBinary, typeof(Byte[]) },
{ SqlDbType.VarChar, typeof(String) },
{ SqlDbType.Variant, typeof(Object) },
{ SqlDbType.Xml, typeof(SqlXml) },
};
Tenga en cuenta que una cosa que tendrá que tener en cuenta es el tamaño/precision-- algunos tipos SQL (por ejemplo varchar
) tienen límites de tamaño, mientras que los tipos de .NET (por ejemplo string
) no lo hacen. Por lo tanto, no es suficiente poder conocer el tipo de .NET más probable ... si está utilizando esto para, por ejemplo, reglas de validación de unidades, también debe ser capaz de evitar que los usuarios entren inválidos (por ejemplo, demasiado grande).) valores al saber más sobre el parámetro, como la precisión. Tenga en cuenta que, si mira dentro de la fuente SqlClient, usan un código especial para manejar casos como la configuración de la precisión de un tipo Decimal a partir de la precisión SQL correspondiente.
Tenga en cuenta que si la única razón por la que necesita el tipo de .NET es poder almacenar datos en un parámetro de proceso almacenado, puede intentar simplemente usar ToString() en todos sus valores .NET, rellenando una cadena en la propiedad Value de SqlParameter, y ver si el framework hará la conversión/el análisis por usted. Por ejemplo, para un parámetro XML o Date, puede ser que pueda salirse con la suya enviando una cadena.
Además, en lugar de utilizar la reflexión para encontrar un método Parse() en cada tipo, dado que hay una lista de tipos conocida (y pequeña), puede obtener un mejor rendimiento utilizando un código de análisis fuertemente tipado para cada una, como código a continuación. (Tenga en cuenta que varios tipos (por ejemplo, SqlDbType).UDT) no tienen necesariamente un analizador obvia method-- tendrá que averiguar cómo desea manejar los.)
public static Dictionary<SqlDbType, Func<string, object>> TypeMapper = new Dictionary<SqlDbType, Func<string, object>>
{
{ SqlDbType.BigInt, s => Int64.Parse(s)},
{ SqlDbType.Binary, s => null }, // TODO: what parser?
{ SqlDbType.Bit, s => Boolean.Parse(s) },
{ SqlDbType.Char, s => s },
{ SqlDbType.Date, s => DateTime.Parse(s) },
{ SqlDbType.DateTime, s => DateTime.Parse(s) },
{ SqlDbType.DateTime2, s => DateTime.Parse(s) },
{ SqlDbType.DateTimeOffset, s => DateTimeOffset.Parse(s) },
{ SqlDbType.Decimal, s => Decimal.Parse(s) },
{ SqlDbType.Float, s => Double.Parse(s) },
{ SqlDbType.Int, s => Int32.Parse(s) },
{ SqlDbType.Money, s => Decimal.Parse(s) },
{ SqlDbType.NChar, s => s },
{ SqlDbType.NText, s => s },
{ SqlDbType.NVarChar, s => s },
{ SqlDbType.Real, s => Single.Parse(s) },
{ SqlDbType.SmallInt, s => Int16.Parse(s) },
{ SqlDbType.SmallMoney, s => Decimal.Parse(s) },
{ SqlDbType.Structured, s => null }, // TODO: what parser?
{ SqlDbType.Text, s => s },
{ SqlDbType.Time, s => TimeSpan.Parse(s) },
{ SqlDbType.Timestamp, s => null }, // TODO: what parser?
{ SqlDbType.TinyInt, s => Byte.Parse(s) },
{ SqlDbType.Udt, s => null }, // consider exception instead
{ SqlDbType.UniqueIdentifier, s => new Guid(s) },
{ SqlDbType.VarBinary, s => null }, // TODO: what parser?
{ SqlDbType.VarChar, s => s },
{ SqlDbType.Variant, s => null }, // TODO: what parser?
{ SqlDbType.Xml, s => s },
};
El código para utilizar anterior es bastante fácil, por ejemplo, :
string valueToSet = "1234";
SqlParameter p = new SqlParameter();
p.SqlDbType = System.Data.SqlDbType.Int;
p.Value = TypeMapper[p.SqlDbType](valueToSet);
¿Qué estás tratando exactamente de hacer? ¿Estoy en lo cierto cuando leí que tienes una colección de SqlParameters y tienes una colección de valores .net? ¿Y desea "convertir" su colección de valores a las propiedades SqlParameter.Value? Ejemplo: SqlParamaters [0].Valor = MagicConvert (Valores [0]); – Zenuka