Asignación de tipos entre CLR y SQL

En LINQ to SQL, el modelo de datos de una base de datos relacional se asigna a un modelo de objetos que se expresa en el lenguaje de programación que prefiera. Cuando se ejecuta la aplicación, LINQ to SQL traduce las consultas integradas en el lenguaje del modelo de objetos en 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 devuelve los resultados a los objetos con los que puede trabajar en su propio lenguaje de programación.

Para traducir datos entre el modelo de objetos y la base de datos, se debe definir una asignación de tipos . LINQ to SQL usa una asignación de tipos para que coincida con cada tipo de Common Language Runtime (CLR) con un tipo de SQL Server determinado. Puede definir asignaciones de tipos y otra información de asignación, como la estructura de la base de datos y las relaciones de tabla, dentro del modelo de objetos con asignación basada en atributos. Como alternativa, puede especificar la información de asignación fuera del modelo de objetos con un archivo de asignación externo. Para obtener más información, consulte Attribute-Based Mapping y External Mapping.

En este tema se describen los siguientes puntos:

Asignación de tipos predeterminados

Puede crear el modelo de objetos o el archivo de asignación externo automáticamente con el Diseñador relacional de objetos (Diseñador de O/R) o la herramienta de línea de comandos SQLMetal. Las asignaciones de tipos predeterminadas para estas herramientas definen qué tipos CLR se eligen para asignar a columnas dentro de la base de datos de SQL Server. Para obtener más información sobre el uso de estas herramientas, vea Creación del modelo de objetos.

También puede usar el CreateDatabase método para crear una base de datos de SQL Server basada en la información de asignación en el modelo de objetos o en el archivo de asignación externo. Las asignaciones de tipos predeterminadas para el CreateDatabase método definen qué tipo de columnas de SQL Server se crean para asignarlos a los tipos CLR del modelo de objetos. Para obtener más información, vea How to: Dynamically Create a Database.

Matriz de comportamiento del entorno de ejecución de asignación de tipos

En el diagrama siguiente se muestra el comportamiento esperado en tiempo de ejecución de asignaciones de tipos específicos cuando los datos se recuperan o se guardan en la base de datos. 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.

Tabla de asignación de tipo de datos de SQL Server a SQL-CLR

Nota:

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 de tipos personalizados

Con LINQ to SQL, no estás limitado a los mapeos de tipos predeterminados utilizados por el Diseñador de O/R, SQLMetal y el método CreateDatabase. Puede crear asignaciones de tipos personalizados especificándolas explícitamente en el archivo DBML. A continuación, puede usar ese archivo DBML para crear el código del modelo de objetos y el archivo de asignación. Para obtener más información, consulte SQL-CLR mapeos de tipos personalizados.

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

Debido a las diferencias de precisión y ejecución entre CLR y SQL Server, puede recibir resultados diferentes o experimentar un comportamiento diferente en función de dónde realice los cálculos. Los cálculos realizados en las consultas LINQ to SQL se traducen realmente a Transact-SQL y, a continuación, se ejecutan en la base de datos de SQL Server. Los cálculos realizados fuera de las consultas LINQ to SQL se ejecutan dentro del contexto de CLR.

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

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

  • SQL Server controla algunas 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.

  • SQL Server puede devolver valores diferentes para algunas funciones mapeadas que el CLR. Por ejemplo, las funciones de igualdad variarán porque SQL Server considera que dos cadenas son iguales si solo difieren 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 CLR System.Enum a tipos de SQL Server de dos maneras:

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

    Al asignar un tipo CLR System.Enum a un tipo numérico SQL, se asigna el valor entero subyacente de CLR System.Enum al valor de la columna de base de datos de SQL Server. Por ejemplo, si un 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.

  • Mapeo a tipos de texto SQL (CHAR, NCHAR, VARCHAR, NVARCHAR)

    Al asignar un tipo CLR System.Enum a un tipo de texto SQL, el valor de la base de datos SQL se asigna a los nombres de los miembros CLR System.Enum . Por ejemplo, si un 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.

Nota:

Al asignar tipos de texto SQL a CLR System.Enum, incluya solo los nombres de los miembros Enum en la columna SQL mapeada. No se admiten otros valores en la columna de SQL asignada a Enum.

La herramienta de línea de comandos O/R Designer y SQLMetal no pueden asignar automáticamente un tipo SQL a una clase CLR Enum . 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 personalizados, consulte SQL-CLR Asignaciones de tipos personalizados.

Dado que una columna SQL destinada a la enumeración será del mismo tipo que otras columnas numéricas y de texto, estas herramientas no reconocerán su intención y realizarán la asignación de manera automática, tal como se describe en las secciones Asignación Numérica y Asignación de Texto y XML. Para obtener más información sobre cómo generar código con el archivo DBML, vea Generación de código en LINQ to SQL.

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

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 CLR que O/R Designer y SQLMetal seleccionan al compilar un modelo de objetos o un archivo de asignación externo basado en la base de datos.

Tipo de datos de SQL Server Asignación de tipos CLR predeterminada usada por O/R 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 usadas por el método para definir qué tipo de columnas SQL se crean para asignar a los tipos CLR definidos en el DataContext.CreateDatabase modelo de objetos o en el archivo de asignación externo.

Tipo CLR Tipo de SQL Server predeterminado usado 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 más información, consulte Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Tipos decimales y de dinero

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

Los tipos SQL Server MONEY y SMALLMONEY, que también están emparejados con el tipo CLR System.Decimal de forma predeterminada, tienen una precisión mucho más limitada, lo que puede provocar errores de desbordamiento o pérdida de datos al guardar datos en la base de datos.

Mapeo de texto y XML

También existen muchos tipos basados en texto y XML que se pueden asignar con LINQ a SQL. En la tabla siguiente se muestran los tipos CLR que O/R Designer y SQLMetal seleccionan al compilar un modelo de objetos o un archivo de asignación externo basado en la base de datos.

Tipo de datos de SQL Server Asignación de tipos CLR predeterminada usada por O/R 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 usadas por el método para definir qué tipo de columnas SQL se crean para asignar a los tipos CLR definidos en el DataContext.CreateDatabase modelo de objetos o en el archivo de asignación externo.

Tipo CLR Tipo de SQL Server predeterminado usado 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 más información, consulte Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Tipos XML

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

  • 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(), puede asignar el objeto a cualquier tipo de texto SQL (CHAR, NCHAR, VARCHARNVARCHAR, , 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 Parse() en la cadena devuelta por la base de datos.

Nota:

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

Asignación de fecha y hora

Con LINQ to SQL, puede asignar muchos tipos de fecha y hora de SQL Server. En la tabla siguiente se muestran los tipos CLR que O/R Designer y SQLMetal seleccionan al compilar un modelo de objetos o un archivo de asignación externo basado en la base de datos.

Tipo de datos de SQL Server Asignación de tipos CLR predeterminada usada por O/R 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 usadas por el método para definir qué tipo de columnas SQL se crean para asignar a los tipos CLR definidos en el DataContext.CreateDatabase modelo de objetos o en el archivo de asignación externo.

Tipo CLR Tipo de SQL Server predeterminado usado 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 dar lugar a excepciones de desbordamiento o pérdida de datos durante la traducción hacia o desde la base de datos. Para más información, consulte Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Nota:

Los tipos DATETIME2de SQL Server , DATETIMEOFFSET, DATEy TIME están disponibles a partir de Microsoft SQL Server 2008. LINQ to SQL admite la asignación a estos nuevos tipos a partir de .NET Framework versión 3.5 SP1.

System.Datetime

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

Las fechas de SQL Server no tienen ningún concepto de TimeZone, una característica que está ampliamente admitida en el CLR. TimeZone Los valores se guardan tal cual en la base de datos sin conversión, independientemente TimeZone de la información original DateTimeKind . 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 sobre los métodos admitidos System.DateTime , vea Métodos System.DateTime.

System.TimeSpan

Microsoft SQL Server 2008 y .NET Framework 3.5 SP1 le permiten asignar el tipo CLR System.TimeSpan al tipo de SQL Server TIME . Sin embargo, hay una gran diferencia entre el intervalo que admite CLR System.TimeSpan y lo que admite el tipo de SQL Server TIME . 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 Métodos System.TimeSpan.

En Microsoft SQL Server 2000 y SQL Server 2005, no se pueden asignar campos de base de datos a TimeSpan. Sin embargo, se admiten operaciones en TimeSpan porque los valores de TimeSpan se pueden devolver de la resta de DateTime o introducirse en una expresión como un 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 hacen que O/R Designer y SQLMetal definan un tipo CLR System.Data.Linq.Binary al compilar un modelo de objetos o un archivo de asignación externo basado en la base de datos.

Tipo de datos de SQL Server Asignación de tipos CLR predeterminada usada por O/R 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 FILESTREAM atributo 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 usadas por el método para definir qué tipo de columnas SQL se crean para asignar a los tipos CLR definidos en el DataContext.CreateDatabase modelo de objetos o en el archivo de asignación externo.

Tipo CLR Tipo de SQL Server predeterminado usado 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 más información, consulte Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

SQL Server FILESTREAM (Gestión de archivos grandes en SQL Server)

El atributo FILESTREAM para columnas VARBINARY(MAX) está disponible a partir de Microsoft SQL Server 2008; puede mapearlo con LINQ to SQL a partir de la versión 3.5 SP1 de .NET Framework.

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

Serialización binaria

Si una clase implementa la ISerializable interfaz , puede serializar un objeto en cualquier campo binario de SQL (BINARY, VARBINARY, IMAGE). El objeto se serializa y deserializa según cómo se implementa la ISerializable interfaz. Para obtener más información, vea Serialización binaria.

Asignaciones varias

En la tabla siguiente se muestran las asignaciones de tipos predeterminadas para algunos tipos diversos que aún no se han mencionado. En la tabla siguiente se muestran los tipos CLR que O/R Designer y SQLMetal seleccionan al compilar un modelo de objetos o un archivo de asignación externo basado en la base de datos.

Tipo de datos de SQL Server Asignación de tipos CLR predeterminada usada por O/R Designer y SQLMetal
UNIQUEIDENTIFIER System.Guid
SQL_VARIANT System.Object

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

Tipo CLR Tipo de SQL Server predeterminado usado 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 más información, consulte Matriz de comportamiento de la asignación de tipos en tiempo de ejecución.

Consulte también