Correspondencia de tipos SQL-CLR (LINQ to SQL)

En LINQ to SQL, el modelo de datos de una base de datos relacional se asigna a un modelo de objetos expresado en el lenguaje de programación que prefiera. Cuando la aplicación se ejecuta, LINQ to SQL convierte las consultas integradas del lenguaje del modelo de objetos a SQL y las envía a la base de datos para su ejecución. Cuando la base de datos devuelve los resultados, LINQ to SQL los vuelve a convertir en objetos con los que pueda trabajar en su propio lenguaje de programación.

Para convertir los datos entre el modelo de objetos y la base de datos, se debe definir una asignación de tipos. LINQ to SQL utiliza una asignación de tipos para que cada tipo de Common Language Runtime (CLR) se corresponda con un tipo de SQL Server concreto. Las asignaciones de tipos y otra información de asignación, como las relaciones de tablas y estructuras de bases de datos, se pueden definir en el modelo de objetos con una asignación basada en atributos. Opcionalmente, la información de asignación se puede especificar fuera del modelo de objetos con un archivo de asignación externo. Para obtener más información, vea Asignación basada en atributos (LINQ to SQL) y Referencia de asignación externa (LINQ to SQL).

En este tema se tratan los puntos siguientes:

  • Asignación de tipos predeterminados

  • Matriz de comportamiento de la asignación de tipos en tiempo de ejecución

  • Diferencias de comportamiento entre la ejecución de CLR y SQL

  • Asignación de enumeración

  • Asignación numérica

  • Asignación de texto y XML

  • Asignación de fecha y hora

  • Asignación binaria

  • Asignaciones varias

Asignación de tipos predeterminados

Puede crear automáticamente el modelo de objetos o el archivo de asignación con Object Relational Designer o la herramienta de línea de comandos SQLMetal. Las asignaciones de tipos predeterminadas de estas herramientas definen qué tipos de CLR se deben elegir para asignarlos a columnas en la base de datos SQL Server. Para obtener más información sobre el uso de estas herramientas, vea Crear el modelo de objetos (LINQ to SQL).

También puede utilizar el método CreateDatabase para crear una base de datos de SQL Server según la información de asignación del modelo de objetos o del archivo de asignación externo. Las asignaciones de tipos predeterminadas del método CreateDatabase definen qué tipo de columnas de SQL Server se deben crear para asignarlas a los tipos de CLR en el modelo de objetos. Para obtener más información, vea Cómo: Crear dinámicamente una base de datos (LINQ to SQL).

Matriz de comportamiento de la asignación de tipos en tiempo de ejecución

En el diagrama siguiente se muestra el comportamiento de las asignaciones de tipos específicos que se espera en tiempo de ejecución, cuando los datos se recuperan de la base de datos o se guardan en ella. Con la excepción de la serialización, LINQ to SQL no admite la asignación entre los tipos de datos de CLR o SQL Server no especificados en esta matriz. Para obtener más información sobre la compatibilidad con la serialización, vea Serialización binaria.

NotaNota

Algunas asignaciones de tipos pueden tener como resultado excepciones de desbordamiento o de pérdida de datos mientras se convierten a la base de datos o desde ella.

Asignación para tipos CLR y SQL

Asignación de tipos personalizada

Con LINQ to SQL, no está limitado a usar las asignaciones de tipos predeterminadas de Object Relational Designer, SQLMetal y el método CreateDatabase. Puede crear asignaciones de tipos personalizadas especificándolas explícitamente en un archivo DBML. Después, puede usar ese archivo para crear el código del modelo de objetos y el archivo de asignación. Para obtener más información, vea Asignaciones de tipos SQL-CLR personalizadas (LINQ to SQL).

Diferencias de comportamiento entre la ejecución de CLR y SQL

Debido a las diferencias entre CLR y SQL Server en cuanto a la precisión y la ejecución, puede recibir diferentes resultados o experimentar un comportamiento distinto en función de dónde se realicen los cálculos. Los cálculos realizados en las consultas LINQ to SQL se traducen, de hecho, a Transact-SQL y después se ejecutan en la base de datos de SQL Server. Los cálculos realizados fuera de las consultas LINQ to SQL se ejecutan en el contexto de CLR.

Por ejemplo, las siguientes son algunas de las diferencias de comportamiento entre CLR y SQL Server:

  • SQL Server ordena ciertos tipos de datos de forma diferente a los datos del tipo equivalente en CLR. Por ejemplo, los datos de SQL Server del tipo UNIQUEIDENTIFIER se ordenan de forma diferente a los datos de CLR del tipo System.Guid.

  • SQL Server trata ciertas operaciones de comparación de cadenas de forma diferente a CLR. En SQL Server, el comportamiento de comparación de cadenas depende de la configuración de intercalación del servidor. Para obtener más información, vea Trabajar con intercalaciones en los Libros en pantalla de SQL Server.

  • SQL Server puede devolver valores diferentes a los que devuelve CLR para algunas funciones asignadas. Por ejemplo, las funciones de igualdad tendrán resultados distintos porque SQL Server considera que dos cadenas son iguales si solo se diferencian en el espacio en blanco final, mientras que CLR considera que no son iguales.

Asignación de enumeración

LINQ to SQL admite la asignación del tipo System.Enum de CLR a tipos de SQL Server de dos maneras:

  • Asignación a tipos SQL numéricos (TINYINT, SMALLINT, INT, BIGINT)

    Al asignar un tipo System.Enum de CLR a un tipo numérico de SQL, el valor entero subyacente del tipo System.Enum de CLR se asigna al valor de la columna de base de datos de SQL Server. Por ejemplo, si un elemento System.Enum denominado DaysOfWeek contiene un miembro denominado Tue con un valor entero subyacente de 3, ese miembro se asigna a un valor de base de datos de 3.

  • Asignación a tipos SQL de texto (CHAR, NCHAR, VARCHAR, NVARCHAR)

    Al asignar un tipo System.Enum de CLR a un tipo de texto de SQL, el valor de la base de datos SQL se asigna a los nombres de los miembros System.Enum de CLR. Por ejemplo, si un tipo System.Enum denominado DaysOfWeek contiene un miembro denominado Tue con un valor entero subyacente de 3, ese miembro se asigna a un valor de base de datos de Tue.

NotaNota

Cuando los tipos de texto de SQL se asignan a System.Enum de CLR, solo se incluyen los nombres de los miembros Enum en la columna de SQL asignada.No se admiten otros valores en la columna de SQL asignada a Enum.

Object Relational Designer y la herramienta de línea de comandos SQLMetal no pueden asignar automáticamente un tipo SQL a una clase Enum de CLR. Debe configurar explícitamente esta asignación personalizando un archivo DBML para que lo usen Object Relational Designer y SQLMetal. Para obtener más información sobre la asignación de tipos personalizada, vea Asignaciones de tipos SQL-CLR personalizadas (LINQ to SQL).

Puesto que una columna SQL de enumeración tendrá el mismo tipo que el resto de las columnas numéricas y de texto; estas herramientas no reconocerán el intento y la asignación se realizará de forma predeterminada tal y como se describe en las siguientes secciones Asignación numérica y Asignación de texto y XML. Para obtener más información sobre el código generador con el archivo DBML, vea Generación de código en LINQ to SQL.

El método DataContext.CreateDatabase crea una columna de SQL de tipo numérico para asignar un tipo System.Enum de CLR.

Asignación numérica

LINQ to SQL permite asignar muchos tipos numéricos de CLR y SQL Server. En la tabla siguiente se muestran los tipos de CLR que Object Relational Designer y SQLMetal seleccionan al crear un modelo de objetos o un archivo de asignación externo de acuerdo con la base de datos.

Tipo de SQL Server

Asignación de tipos de CLR predeterminada utilizada por Object Relational Designer y SQLMetal

BIT

System.Boolean

TINYINT

System.Int16

INT

System.Int32

BIGINT

System.Int64

SMALLMONEY

System.Decimal

MONEY

System.Decimal

DECIMAL

System.Decimal

NUMERIC

System.Decimal

REAL/FLOAT(24)

System.Single

FLOAT/FLOAT(53)

System.Double

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas que el método DataContext.CreateDatabase utiliza para definir qué tipo de columnas de SQL se deben crear para asignarlas a los tipos de CLR definidos en el modelo de objetos o en el archivo de asignación externo.

Tipo CLR

Tipo predeterminado de SQL Server utilizado por DataContext.CreateDatabase

System.Boolean

BIT

System.Byte

TINYINT

System.Int16

SMALLINT

System.Int32

INT

System.Int64

BIGINT

System.SByte

SMALLINT

System.UInt16

INT

System.UInt32

BIGINT

System.UInt64

DECIMAL(20)

System.Decimal

DECIMAL(29,4)

System.Single

REAL

System.Double

FLOAT

Hay muchas otras asignaciones de tipos numéricos entre las que puede elegir, pero algunas pueden tener como resultado excepciones de desbordamiento o de pérdida de datos mientras se trasladan a la base de datos o desde ella. Para obtener más información, vea Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Tipos Decimal y Money

La precisión predeterminada del tipo DECIMAL de SQL Server (18 dígitos decimales a la derecha y a la izquierda del separador decimal) es menor que la precisión del tipo Decimal de CLR con el que se empareja de forma predeterminada. Esto puede producir una pérdida de precisión cuando los datos se guardan en la base de datos. Sin embargo, puede ocurrir exactamente lo contrario si el tipo DECIMAL de SQL Server se configura con más de 29 dígitos de precisión. Cuando se ha configurado un tipo DECIMAL de SQL Server con mayor precisión que el tipo System.Decimal de CLR, la pérdida de precisión se produce al recuperar los datos de la base de datos.

Los tipos MONEY y SMALLMONEY de SQL Server, que también están emparejados con el tipo System.Decimal de CLR de forma predeterminada, tienen mucha menos precisión, por lo que pueden producirse excepciones de desbordamiento o de pérdida de datos al guardar los datos en la base de datos.

Asignación de texto y XML

También hay muchos tipos XML y basados en texto que se pueden asignar con LINQ to SQL. En la tabla siguiente se muestran los tipos de CLR que Object Relational Designer y SQLMetal seleccionan al crear un modelo de objetos o un archivo de asignación externo de acuerdo con la base de datos.

Tipo de SQL Server

Asignación de tipos de CLR predeterminada utilizada por Object Relational Designer y SQLMetal

CHAR

System.String

NCHAR

System.String

VARCHAR

System.String

NVARCHAR

System.String

TEXT

System.String

NTEXT

System.String

XML

System.Xml.Linq.XElement

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas que el método DataContext.CreateDatabase utiliza para definir qué tipo de columnas de SQL se deben crear para asignarlas a los tipos de CLR definidos en el modelo de objetos o en el archivo de asignación externo.

Tipo CLR

Tipo predeterminado de SQL Server utilizado por DataContext.CreateDatabase

System.Char

NCHAR(1)

System.String

NVARCHAR(4000)

System.Char[]

NVARCHAR(4000)

Tipo personalizado que implementa Parse() y ToString()

NVARCHAR(MAX)

Hay muchas otras asignaciones de XML y basadas en texto entre las que puede elegir, pero algunas pueden tener como resultado excepciones de desbordamiento o de pérdida de datos mientras se trasladan a o desde la base de datos. Para obtener más información, vea Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Tipos XML

El tipo de datos XML de SQL Server está disponible a partir de Microsoft SQL Server 2005. Puede asignar el tipo de datos XML de SQL Server a XElement, XDocument o String. Si la columna almacena fragmentos XML que no se pueden leer en XElement, dicha columna debe asignarse a String para evitar errores en tiempo de ejecución. Entre los fragmentos XML que se deben asignar a String se incluyen los siguientes:

  • Una secuencia de elementos XML

  • Atributos

  • Identificadores públicos (PI)

  • Comentarios

Aunque puede asignar XElement y XDocument a SQL Server como se muestra en Matriz de comportamiento de la asignación de tipos en tiempo de ejecución, el método DataContext.CreateDatabase no dispone de ninguna asignación predeterminada de tipos de SQL Server para estos tipos.

Tipos personalizados

Si una clase implementa Parse() y ToString(), el objeto se puede asignar a cualquier tipo de texto de SQL (CHAR, NCHAR, VARCHAR, NVARCHAR, TEXT, NTEXT, XML). El objeto se almacena en la base de datos enviando el valor devuelto por ToString() a la columna de base de datos asignada. El objeto se reconstruye invocando a Parse() en la cadena devuelta por la base de datos.

NotaNota

LINQ to SQL no admite la serialización mediante System.Xml.Serialization.IXmlSerializable.

Asignación de fecha y hora

Con LINQ to SQL, se pueden asignar muchos tipos de fecha y hora de SQL Server. En la tabla siguiente se muestran los tipos de CLR que Object Relational Designer y SQLMetal seleccionan al crear un modelo de objetos o un archivo de asignación externo de acuerdo con la base de datos.

Tipo de SQL Server

Asignación de tipos de CLR predeterminada utilizada por Object Relational Designer y SQLMetal

SMALLDATETIME

System.DateTime

DATETIME

System.DateTime

DATETIME2

System.DateTime

DATETIMEOFFSET

System.DateTimeOffset

DATE

System.DateTime

TIME

System.TimeSpan

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas que el método DataContext.CreateDatabase utiliza para definir qué tipo de columnas de SQL se deben crear para asignarlas a los tipos de CLR definidos en el modelo de objetos o en el archivo de asignación externo.

Tipo CLR

Tipo predeterminado de SQL Server utilizado por DataContext.CreateDatabase

System.DateTime

DATETIME

System.DateTimeOffset

DATETIMEOFFSET

System.TimeSpan

TIME

Hay muchas otras asignaciones de fecha y hora entre las que puede elegir, pero algunas pueden tener como resultado excepciones de desbordamiento o de pérdida de datos mientras se trasladan a o desde la base de datos. Para obtener más información, vea Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

NotaNota

Los tipos de SQL Server DATETIME2, DATETIMEOFFSET, DATE y TIME están disponibles a partir de Microsoft SQL Server 2008.LINQ to SQL admite la asignación a estos tipos nuevos a partir del Service Pack 1 de .NET Framework 3.5.

System.Datetime

El intervalo y la precisión del tipo System.DateTime de CLR son mayores que el intervalo y la precisión del tipo DATETIME de SQL Server, que es la asignación de tipos predeterminada para el método DataContext.CreateDatabase. Para evitar las excepciones relacionadas con los datos que están fuera del intervalo de DATETIME, utilice DATETIME2, que está disponible a partir de Microsoft SQL Server 2008. DATETIME2 puede alcanzar la precisión y el intervalo del tipo System.DateTime de CLR.

Las fechas de SQL Server no disponen del concepto de TimeZone, que es una característica totalmente admitida en CLR. Los valores de TimeZone se guardan tal como están en la base de datos sin conversión de TimeZone, independientemente de la información de DateTimeKind original. Cuando los valores DateTime se recuperan de la base de datos, su valor se carga tal cual en DateTime, con un valor DateTimeKind de Unspecified. Para obtener más información acerca de los métodos de System.DateTime compatibles, vea System.DateTime (métodos - LINQ to SQL).

System.TimeSpan

Microsoft SQL Server 2008 y .NET Framework 3.5 SP1 permiten asignar el tipo System.TimeSpan de CLR al tipo TIME de SQL Server. Sin embargo, existe una gran diferencia entre el intervalo que admite el tipo System.TimeSpan de CLR y el que admite el tipo TIME de SQL Server. La asignación de valores menores que 0 horas o mayores que 23:59:59.9999999 horas al tipo TIME de SQL producirá excepciones de desbordamiento. Para obtener más información, vea System.TimeSpan (métodos - LINQ to SQL).

En Microsoft SQL Server 2000 y SQL Server 2005, no se pueden asignar campos de base de datos a TimeSpan. Sin embargo, se admiten las operaciones en TimeSpan porque se pueden devolver valores TimeSpan a partir de la sustracción de DateTime o se pueden incluir en una expresión como una variable literal o una variable enlazada.

Asignación binaria

Hay muchos tipos de SQL Server que se pueden asignar al tipo System.Data.Linq.Binary de CLR. En la tabla siguiente se muestran los tipos de SQL Server que provocan que Object Relational Designer y SQLMetal definan un tipo System.Data.Linq.Binary de CLR al crear un modelo de objetos o un archivo de asignación externo de acuerdo con la base de datos.

Tipo de SQL Server

Asignación de tipos de CLR predeterminada utilizada por Object Relational Designer y SQLMetal

BINARY(50)

System.Data.Linq.Binary

VARBINARY(50)

System.Data.Linq.Binary

VARBINARY(MAX)

System.Data.Linq.Binary

VARBINARY(MAX) con el atributo FILESTREAM

System.Data.Linq.Binary

IMAGE

System.Data.Linq.Binary

TIMESTAMP

System.Data.Linq.Binary

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas que el método DataContext.CreateDatabase utiliza para definir qué tipo de columnas de SQL se deben crear para asignarlas a los tipos de CLR definidos en el modelo de objetos o en el archivo de asignación externo.

Tipo CLR

Tipo predeterminado de SQL Server utilizado por DataContext.CreateDatabase

System.Data.Linq.Binary

VARBINARY(MAX)

System.Byte

VARBINARY(MAX)

System.Runtime.Serialization.ISerializable

VARBINARY(MAX)

Hay muchas otras asignaciones binarias entre las que puede elegir, pero algunas pueden tener como resultado excepciones de desbordamiento o de pérdida de datos mientras se trasladan a o desde la base de datos. Para obtener más información, vea Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

SQL Server FILESTREAM

El atributo FILESTREAM para las columnas VARBINARY(MAX) está disponible a partir de Microsoft SQL Server 2008; se le pueden asignar elementos con LINQ to SQL a partir del Service Pack 1 de .NET Framework 3.5.

Aunque puede asignar columnas VARBINARY(MAX) con el atributo FILESTREAM a objetos Binary, el método DataContext.CreateDatabase no puede crear columnas automáticamente con el atributo FILESTREAM. Para obtener más información acerca de FILESTREAM, vea Información general de FILESTREAM en los Libros en pantalla de SQL Server.

Serialización binaria

Si una clase implementa la interfaz ISerializable, se puede serializar un objeto en cualquier campo binario de SQL (BINARY, VARBINARY, IMAGE). El objeto se serializa o deserializa de acuerdo con la forma en que se haya implementado la interfaz ISerializable. Para obtener más información, vea Serialización binaria.

Asignaciones varias

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas para varios tipos que aún no se han mencionado. En la tabla siguiente se muestran los tipos de CLR que Object Relational Designer y SQLMetal seleccionan al crear un modelo de objetos o un archivo de asignación externo de acuerdo con la base de datos.

Tipo de SQL Server

Asignación de tipos de CLR predeterminada utilizada por Object Relational Designer y SQLMetal

UNIQUEIDENTIFIER

System.Guid

SQL_VARIANT

System.Object

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas que el método DataContext.CreateDatabase utiliza para definir qué tipo de columnas de SQL se deben crear para asignarlas a los tipos de CLR definidos en el modelo de objetos o en el archivo de asignación externo.

Tipo CLR

Tipo predeterminado de SQL Server utilizado por DataContext.CreateDatabase

System.Guid

UNIQUEIDENTIFIER

System.Object

SQL_VARIANT

LINQ to SQL no admite ninguna otra asignación de tipos para estos tipos varios. Para obtener más información, vea Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Vea también

Referencia

Asignación basada en atributos (LINQ to SQL)

Referencia de asignación externa (LINQ to SQL)

Discordancias de tipos SQL-CLR (LINQ to SQL)

Otros recursos

Tipos de datos y funciones (LINQ to SQL)