Saltar al contenido

Tipo de sistema .NET a SqlDbType

Este dilema se puede abordar de diversas formas, pero te enseñamos la respuesta más completa en nuestra opinión.

Solución:

Su enfoque es un buen comienzo, pero completar ese diccionario solo debe hacerse una vez, como dice Ian en un comentario.

Aquí hay un GIST que se basa en la misma idea, aunque no convierte entre los mismos conjuntos de tipos: https://gist.github.com/abrahamjp/858392

Advertencia

Tengo un ejemplo de trabajo a continuación, pero debe tener en cuenta que este enfoque tiene algunos problemas. Por ejemplo:

  • Para string, ¿cómo eliges el correcto entre Char, NChar, VarChar, NVarChar, Text o NText(o incluso Xml, quizás)?
  • Y para manchas como byte[], deberías usar Binary, VarBinary o Image?
  • Para decimal, float y double, deberías ir por Decimal, Float, Money, SmallMoney o Real?
  • Para DateTime, necesitas DateTime2, DateTimeOffset, DateTime, o SmallDateTime?
  • Estas usando Nullable tipos, como int?? Esas probablemente deberían dar lo mismo SqlDbType como el tipo subyacente.

Además, solo brindando un Type no le dice nada sobre otras restricciones, como el tamaño y la precisión del campo. Tomar la decisión correcta también se trata de cómo se utilizan los datos en su aplicación y cómo se almacenan en la base de datos.

Lo mejor que puede hacer es dejar que un ORM lo haga por usted.

Código

public static class SqlHelper

    private static Dictionary typeMap;

    // Create and populate the dictionary in the static constructor
    static SqlHelper()
    
        typeMap = new Dictionary();

        typeMap[typeof(string)]         = SqlDbType.NVarChar;
        typeMap[typeof(char[])]         = SqlDbType.NVarChar;
        typeMap[typeof(byte)]           = SqlDbType.TinyInt;
        typeMap[typeof(short)]          = SqlDbType.SmallInt;
        typeMap[typeof(int)]            = SqlDbType.Int;
        typeMap[typeof(long)]           = SqlDbType.BigInt;
        typeMap[typeof(byte[])]         = SqlDbType.Image;
        typeMap[typeof(bool)]           = SqlDbType.Bit;
        typeMap[typeof(DateTime)]       = SqlDbType.DateTime2;
        typeMap[typeof(DateTimeOffset)] = SqlDbType.DateTimeOffset;
        typeMap[typeof(decimal)]        = SqlDbType.Money;
        typeMap[typeof(float)]          = SqlDbType.Real;
        typeMap[typeof(double)]         = SqlDbType.Float;
        typeMap[typeof(TimeSpan)]       = SqlDbType.Time;
        /* ... and so on ... */
    

    // Non-generic argument-based method
    public static SqlDbType GetDbType(Type giveType)
    
        // Allow nullable types to be handled
        giveType = Nullable.GetUnderlyingType(giveType) ?? giveType;

        if (typeMap.ContainsKey(giveType))
        
            return typeMap[giveType];
        

        throw new ArgumentException($"giveType.FullName is not a supported .NET class");
    

    // Generic version
    public static SqlDbType GetDbType()
    
        return GetDbType(typeof(T));
    

Y así es como lo usarías:

var sqlDbType = SqlHelper.GetDbType();
// or:
var sqlDbType = SqlHelper.GetDbType(typeof(DateTime?));
// or:
var sqlDbType = SqlHelper.GetDbType(property.PropertyType);

Parece que este tipo de tabla de búsqueda ya está disponible, aunque no en System.Data (o .Object o .Type) sino en System.Web.

Proyecto -> Agregar referencia -> System.Web -> Aceptar

Entonces https://msdn.microsoft.com/en-us/library/system.data.sqldbtype(v=vs.110).aspx también dice

Al configurar los parámetros del comando, SqlDbType y DbType están vinculados. Por lo tanto, configurar DbType cambia SqlDbType a un SqlDbType compatible.

Entonces, esto debería funcionar teóricamente;)

using Microsoft.SqlServer.Server; // SqlDataRecord and SqlMetaData
using System;
using System.Collections; // IEnumerator and IEnumerable
using System.Collections.Generic; // general IEnumerable and IEnumerator
using System.Data; // DataTable and SqlDataType
using System.Data.SqlClient; // SqlConnection, SqlCommand, and SqlParameter
using System.Web.UI.WebControls; // for Parameters.Convert... functions

private static SqlDbType TypeToSqlDbType(Type t) 
    DbType dbtc = Parameters.ConvertTypeCodeToDbType(t.GetTypeCodeImpl());
    SqlParameter sp = new SqlParameter();
    // DbParameter dp = new DbParameter();
    // dp.DbType = dbtc;
    sp.DbType = dbtc;
    return sp.SqlDbType;

Aquí puedes ver las reseñas y valoraciones de los usuarios

Si te animas, puedes dejar un escrito acerca de qué te ha parecido este enunciado.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *