smallint - tipo de dato tinyint en c#
¿Alguien obtuvo una función C#que mapea el tipo de datos SQL de una columna con su equivalente CLR? (12)
¿Por qué no crear un conjunto de datos tipeados y hacer que el diseñador de VS haga el mapeo por usted? A menos que el proyecto tenga que adaptarse en tiempo de ejecución a diferentes esquemas, entonces debe usar técnicas de generación de código para crear sus clases, ya sea con los diseñadores incorporados (es decir, conjuntos de datos tipados) o personalizados (esquema-> XML-> XSLT->. cs).
Estoy sentado para escribir una instrucción switch () masiva para convertir los tipos de datos SQL en tipos de datos CLR con el fin de generar clases a partir de procedimientos almacenados MSSQL. Estoy usando esta tabla como referencia. Antes de llegar demasiado lejos en lo que probablemente tomará todo el día y ser un gran dolor para probarlo, me gustaría llamar a la comunidad SO para ver si alguien más ya ha escrito o encontrado algo en C # para lograr esto aparentemente común y tarea ciertamente tediosa.
Aquí hay una revisión que acepta anulables.
public static Type GetClrType(SqlDbType sqlType, bool isNullable)
{
switch (sqlType)
{
case SqlDbType.BigInt:
return isNullable ? typeof(long?) : typeof(long);
case SqlDbType.Binary:
case SqlDbType.Image:
case SqlDbType.Timestamp:
case SqlDbType.VarBinary:
return typeof(byte[]);
case SqlDbType.Bit:
return isNullable ? typeof(bool?) : typeof(bool);
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.NText:
case SqlDbType.NVarChar:
case SqlDbType.Text:
case SqlDbType.VarChar:
case SqlDbType.Xml:
return typeof(string);
case SqlDbType.DateTime:
case SqlDbType.SmallDateTime:
case SqlDbType.Date:
case SqlDbType.Time:
case SqlDbType.DateTime2:
return isNullable ? typeof(DateTime?) : typeof(DateTime);
case SqlDbType.Decimal:
case SqlDbType.Money:
case SqlDbType.SmallMoney:
return isNullable ? typeof(decimal?) : typeof(decimal);
case SqlDbType.Float:
return isNullable ? typeof(double?) : typeof(double);
case SqlDbType.Int:
return isNullable ? typeof(int?) : typeof(int);
case SqlDbType.Real:
return isNullable ? typeof(float?) : typeof(float);
case SqlDbType.UniqueIdentifier:
return isNullable ? typeof(Guid?) : typeof(Guid);
case SqlDbType.SmallInt:
return isNullable ? typeof(short?) : typeof(short);
case SqlDbType.TinyInt:
return isNullable ? typeof(byte?) : typeof(byte);
case SqlDbType.Variant:
case SqlDbType.Udt:
return typeof(object);
case SqlDbType.Structured:
return typeof(DataTable);
case SqlDbType.DateTimeOffset:
return isNullable ? typeof(DateTimeOffset?) : typeof(DateTimeOffset);
default:
throw new ArgumentOutOfRangeException("sqlType");
}
}
Creo que no hay nada integrado para eso, pero puedes usar VS para generar clases para tus tablas y luego intentar editarlas
Entiendo que está discutiendo la redacción de una declaración de cambio, pero aquí hay una alternativa para el Servidor SQL (los conceptos similares funcionan para otros DB)
Considere usar SysObjects para recuperar los tipos de datos completos y generar su clase:
declare @ProcName varchar(255)
select @ProcName=''Table, View, or Proc''
SELECT --DISTINCT
b.name
, c.name Type
, b.xtype
, b.length
, b.isoutparam
FROM
sysObjects a
INNER JOIN sysCOLUMNs b ON a.id=b.id
INNER JOIN systypes c ON b.xtype=c.xtype
WHERE
a.name=@ProcName
order by b.colorder
Ahora solo está enumerando una DataTable en lugar de la declaración más larga.
Este es el que usamos. Es posible que desee modificarlo (por ejemplo, los tipos de nulos / nullable, etc.), pero debe ahorrarle la mayor parte de la escritura.
public static Type GetClrType(SqlDbType sqlType)
{
switch (sqlType)
{
case SqlDbType.BigInt:
return typeof(long?);
case SqlDbType.Binary:
case SqlDbType.Image:
case SqlDbType.Timestamp:
case SqlDbType.VarBinary:
return typeof(byte[]);
case SqlDbType.Bit:
return typeof(bool?);
case SqlDbType.Char:
case SqlDbType.NChar:
case SqlDbType.NText:
case SqlDbType.NVarChar:
case SqlDbType.Text:
case SqlDbType.VarChar:
case SqlDbType.Xml:
return typeof(string);
case SqlDbType.DateTime:
case SqlDbType.SmallDateTime:
case SqlDbType.Date:
case SqlDbType.Time:
case SqlDbType.DateTime2:
return typeof(DateTime?);
case SqlDbType.Decimal:
case SqlDbType.Money:
case SqlDbType.SmallMoney:
return typeof(decimal?);
case SqlDbType.Float:
return typeof(double?);
case SqlDbType.Int:
return typeof(int?);
case SqlDbType.Real:
return typeof(float?);
case SqlDbType.UniqueIdentifier:
return typeof(Guid?);
case SqlDbType.SmallInt:
return typeof(short?);
case SqlDbType.TinyInt:
return typeof(byte?);
case SqlDbType.Variant:
case SqlDbType.Udt:
return typeof(object);
case SqlDbType.Structured:
return typeof(DataTable);
case SqlDbType.DateTimeOffset:
return typeof(DateTimeOffset?);
default:
throw new ArgumentOutOfRangeException("sqlType");
}
}
Esto no responde directamente a la pregunta tal como se le preguntó, pero responde a una pregunta relacionada común. Una vez que tenga un IDataReader
, puede llamar a IDataRecord.GetFieldType(int)
para "[obtener] la información de Type
correspondiente al tipo de Object
que se devolverá desde GetValue
".
Incluyo esta extensión (podría intercambiar fácilmente la clave de cadena en el diccionario para SqlDbType, ya que Greg implementó - o incluso admite ambas cosas - en mi modelo y expone una propiedad que convierte el tipo de CLR:
namespace X.Domain.Model
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class StoredProcedureParameter : DomainObject
{
public StoredProcedureParameter() { }
public string StoredProcedure { get; set; }
public string ProcedureSchema { get; set; }
public string ProcedureName { get; set; }
public string ParameterName { get; set; }
public string ParameterOrder { get; set; }
public string ParameterMode { get; set; }
public string SqlDataType { get; set; }
public Type DataType { get { return this.SqlDataType.ToClrType(); } }
}
static class StoredProcedureParameterExtensions
{
private static Dictionary<string, Type> Mappings;
public static StoredProcedureParameterExtensions()
{
Mappings = new Dictionary<string, Type>();
Mappings.Add("bigint", typeof(Int64));
Mappings.Add("binary", typeof(Byte[]));
Mappings.Add("bit", typeof(Boolean));
Mappings.Add("char", typeof(String));
Mappings.Add("date", typeof(DateTime));
Mappings.Add("datetime", typeof(DateTime));
Mappings.Add("datetime2", typeof(DateTime));
Mappings.Add("datetimeoffset", typeof(DateTimeOffset));
Mappings.Add("decimal", typeof(Decimal));
Mappings.Add("float", typeof(Double));
Mappings.Add("image", typeof(Byte[]));
Mappings.Add("int", typeof(Int32));
Mappings.Add("money", typeof(Decimal));
Mappings.Add("nchar", typeof(String));
Mappings.Add("ntext", typeof(String));
Mappings.Add("numeric", typeof(Decimal));
Mappings.Add("nvarchar", typeof(String));
Mappings.Add("real", typeof(Single));
Mappings.Add("rowversion", typeof(Byte[]));
Mappings.Add("smalldatetime", typeof(DateTime));
Mappings.Add("smallint", typeof(Int16));
Mappings.Add("smallmoney", typeof(Decimal));
Mappings.Add("text", typeof(String));
Mappings.Add("time", typeof(TimeSpan));
Mappings.Add("timestamp", typeof(Byte[]));
Mappings.Add("tinyint", typeof(Byte));
Mappings.Add("uniqueidentifier", typeof(Guid));
Mappings.Add("varbinary", typeof(Byte[]));
Mappings.Add("varchar", typeof(String));
}
public static Type ToClrType(this string sqlType)
{
Type datatype = null;
if (Mappings.TryGetValue(sqlType, out datatype))
return datatype;
throw new TypeLoadException(string.Format("Can not load CLR Type from {0}", sqlType));
}
}
}
No necesita una función. Creo que puede estar buscando
dt.Columns[i].DataType.UnderlyingSystemType
dt - dataTable
Esto devolverá el tipo de CLR para la columna correspondiente. Espero que esto ayude y, por cierto, esta es mi primera respuesta al desbordamiento de la pila
Normalmente solo uso la propiedad Value para convertir un SqlType a un tipo .NET nativo. Esto hace el trabajo la mayor parte del tiempo. Si tengo una caja de esquina, solo escribiré una función de ayuda rápida.
int i = dataReader.GetSqlInt32(0).Value;
Puedes probar Wizardby . Sin embargo, se correlaciona desde tipos de datos llamados "nativos" a DbType
, que luego son triviales para convertir a tipos CLR. Si esto se ajusta, necesitará un IDbTypeMapper
apropiado, ya sea SqlServer2000TypeMapper
o SqlServer2005TypeMapper
.
/****** Object: Table [dbo].[DbVsCSharpTypes] Script Date: 03/20/2010 03:07:56 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N''[dbo].[DbVsCSharpTypes]'')
AND type in (N''U''))
DROP TABLE [dbo].[DbVsCSharpTypes]
GO
/****** Object: Table [dbo].[DbVsCSharpTypes] Script Date: 03/20/2010 03:07:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[DbVsCSharpTypes](
[DbVsCSharpTypesId] [int] IDENTITY(1,1) NOT NULL,
[Sql2008DataType] [varchar](200) NULL,
[CSharpDataType] [varchar](200) NULL,
[CLRDataType] [varchar](200) NULL,
[CLRDataTypeSqlServer] [varchar](2000) NULL,
CONSTRAINT [PK_DbVsCSharpTypes] PRIMARY KEY CLUSTERED
(
[DbVsCSharpTypesId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET NOCOUNT ON;
SET XACT_ABORT ON;
GO
SET IDENTITY_INSERT [dbo].[DbVsCSharpTypes] ON;
BEGIN TRANSACTION;
INSERT INTO [dbo].[DbVsCSharpTypes]([DbVsCSharpTypesId], [Sql2008DataType], [CSharpDataType], [CLRDataType], [CLRDataTypeSqlServer])
SELECT 1, N''bigint'', N''long'', N''Int64, Nullable<Int64>'', N''SqlInt64'' UNION ALL
SELECT 2, N''binary'', N''byte[]'', N''Byte[]'', N''SqlBytes, SqlBinary'' UNION ALL
SELECT 3, N''bit'', N''bool'', N''Boolean, Nullable<Boolean>'', N''SqlBoolean'' UNION ALL
SELECT 4, N''char'', N''char'', NULL, NULL UNION ALL
SELECT 5, N''cursor'', NULL, NULL, NULL UNION ALL
SELECT 6, N''date'', N''DateTime'', N''DateTime, Nullable<DateTime>'', N''SqlDateTime'' UNION ALL
SELECT 7, N''datetime'', N''DateTime'', N''DateTime, Nullable<DateTime>'', N''SqlDateTime'' UNION ALL
SELECT 8, N''datetime2'', N''DateTime'', N''DateTime, Nullable<DateTime>'', N''SqlDateTime'' UNION ALL
SELECT 9, N''DATETIMEOFFSET'', N''DateTimeOffset'', N''DateTimeOffset'', N''DateTimeOffset, Nullable<DateTimeOffset>'' UNION ALL
SELECT 10, N''decimal'', N''decimal'', N''Decimal, Nullable<Decimal>'', N''SqlDecimal'' UNION ALL
SELECT 11, N''float'', N''double'', N''Double, Nullable<Double>'', N''SqlDouble'' UNION ALL
SELECT 12, N''geography'', NULL, NULL, N''SqlGeography is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.'' UNION ALL
SELECT 13, N''geometry'', NULL, NULL, N''SqlGeometry is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.'' UNION ALL
SELECT 14, N''hierarchyid'', NULL, NULL, N''SqlHierarchyId is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack.'' UNION ALL
SELECT 15, N''image'', NULL, NULL, NULL UNION ALL
SELECT 16, N''int'', N''int'', N''Int32, Nullable<Int32>'', N''SqlInt32'' UNION ALL
SELECT 17, N''money'', N''decimal'', N''Decimal, Nullable<Decimal>'', N''SqlMoney'' UNION ALL
SELECT 18, N''nchar'', N''string'', N''String, Char[]'', N''SqlChars, SqlString'' UNION ALL
SELECT 19, N''ntext'', NULL, NULL, NULL UNION ALL
SELECT 20, N''numeric'', N''decimal'', N''Decimal, Nullable<Decimal>'', N''SqlDecimal'' UNION ALL
SELECT 21, N''nvarchar'', N''string'', N''String, Char[]'', N''SqlChars, SqlStrinG SQLChars is a better match for data transfer and access, and SQLString is a better match for performing String operations.'' UNION ALL
SELECT 22, N''nvarchar(1), nchar(1)'', N''string'', N''Char, String, Char[], Nullable<char>'', N''SqlChars, SqlString'' UNION ALL
SELECT 23, N''real'', N''single'', N''Single, Nullable<Single>'', N''SqlSingle'' UNION ALL
SELECT 24, N''rowversion'', N''byte[]'', N''Byte[]'', NULL UNION ALL
SELECT 25, N''smallint'', N''smallint'', N''Int16, Nullable<Int16>'', N''SqlInt16'' UNION ALL
SELECT 26, N''smallmoney'', N''decimal'', N''Decimal, Nullable<Decimal>'', N''SqlMoney'' UNION ALL
SELECT 27, N''sql_variant'', N''object'', N''Object'', NULL UNION ALL
SELECT 28, N''table'', NULL, NULL, NULL UNION ALL
SELECT 29, N''text'', N''string'', NULL, NULL UNION ALL
SELECT 30, N''time'', N''TimeSpan'', N''TimeSpan, Nullable<TimeSpan>'', N''TimeSpan'' UNION ALL
SELECT 31, N''timestamp'', NULL, NULL, NULL UNION ALL
SELECT 32, N''tinyint'', N''byte'', N''Byte, Nullable<Byte>'', N''SqlByte'' UNION ALL
SELECT 33, N''uniqueidentifier'', N''Guid'', N''Guid, Nullable<Guid>'', N''SqlGuidUser-defined type(UDT)The same class that is bound to the user-defined type in the same assembly or a dependent assembly.'' UNION ALL
SELECT 34, N''varbinary '', N''byte[]'', N''Byte[]'', N''SqlBytes, SqlBinary'' UNION ALL
SELECT 35, N''varbinary(1), binary(1)'', N''byte'', N''byte, Byte[], Nullable<byte>'', N''SqlBytes, SqlBinary'' UNION ALL
SELECT 36, N''varchar'', NULL, NULL, NULL UNION ALL
SELECT 37, N''xml'', NULL, NULL, N''SqlXml''
COMMIT;
RAISERROR (N''[dbo].[DbVsCSharpTypes]: Insert Batch: 1.....Done!'', 10, 1) WITH NOWAIT;
GO
SET IDENTITY_INSERT [dbo].[DbVsCSharpTypes] OFF;
internal Type type(SqlDbType sqltype)
{
Type resulttype = null;
Dictionary<SqlDbType, Type> Types = new Dictionary<SqlDbType, Type>();
Types.Add(SqlDbType.BigInt, typeof(Int64));
Types.Add(SqlDbType.Binary, typeof(Byte[]));
Types.Add(SqlDbType.Bit, typeof(Boolean));
Types.Add(SqlDbType.Char, typeof(String));
Types.Add(SqlDbType.Date, typeof(DateTime));
Types.Add(SqlDbType.DateTime, typeof(DateTime));
Types.Add(SqlDbType.DateTime2, typeof(DateTime));
Types.Add(SqlDbType.DateTimeOffset, typeof(DateTimeOffset));
Types.Add(SqlDbType.Decimal, typeof(Decimal));
Types.Add(SqlDbType.Float, typeof(Double));
Types.Add(SqlDbType.Image, typeof(Byte[]));
Types.Add(SqlDbType.Int, typeof(Int32));
Types.Add(SqlDbType.Money, typeof(Decimal));
Types.Add(SqlDbType.NChar, typeof(String));
Types.Add(SqlDbType.NText, typeof(String));
Types.Add(SqlDbType.NVarChar, typeof(String));
Types.Add(SqlDbType.Real, typeof(Single));
Types.Add(SqlDbType.SmallDateTime, typeof(DateTime));
Types.Add(SqlDbType.SmallInt, typeof(Int16));
Types.Add(SqlDbType.SmallMoney, typeof(Decimal));
Types.Add(SqlDbType.Text, typeof(String));
Types.Add(SqlDbType.Time, typeof(TimeSpan));
Types.Add(SqlDbType.Timestamp, typeof(Byte[]));
Types.Add(SqlDbType.TinyInt, typeof(Byte));
Types.Add(SqlDbType.UniqueIdentifier, typeof(Guid));
Types.Add(SqlDbType.VarBinary, typeof(Byte[]));
Types.Add(SqlDbType.VarChar, typeof(String));
Types.TryGetValue(sqltype, out resulttype);
return resulttype;
}
internal SqlDbType type(Type systype)
{
SqlDbType resulttype = SqlDbType.NVarChar;
Dictionary<Type, SqlDbType> Types = new Dictionary<Type, SqlDbType>();
Types.Add(typeof(Boolean), SqlDbType.Bit);
Types.Add(typeof(String), SqlDbType.NVarChar);
Types.Add(typeof(DateTime), SqlDbType.DateTime);
Types.Add(typeof(Int16), SqlDbType.Int);
Types.Add(typeof(Int32), SqlDbType.Int);
Types.Add(typeof(Int64), SqlDbType.Int);
Types.Add(typeof(Decimal), SqlDbType.Float);
Types.Add(typeof(Double), SqlDbType.Float);
Types.TryGetValue(systype, out resulttype);
return resulttype;
}