Las siguientes secciones dan respuesta a algunos problemas comunes que podría encontrar al implementar LINQ.
En Solución de problemas (LINQ to SQL) se tratan otros posibles problemas que puedan surgir.
No se puede conectar
No puedo conectarme a mi base de datos.
Asegúrate de que tu cadena de conexión es correcta y de que tu instancia de SQL server se está ejecutando. También ten en cuenta que LINQ to SQL requiere que el protocolo Canalizaciones con nombre esté habilitado. Para obtener más información, consulta Aprender con tutoriales.
La base de datos pierde los cambios realizados
Realicé un cambio en los datos de la base de datos, pero, cuando volví a ejecutar mi aplicación, el cambio ya no estaba.
Asegúrese de que llama a SubmitChanges para guardar los resultados en la base de datos.
Conexión a bases de datos: ¿cuánto tiempo permanece abierta?
¿Cuánto tiempo permanece abierta mi conexión a una base de datos?
Normalmente, una conexión permanece abierta hasta que se utilizan los resultados de la consulta. Si espera que los resultados tarden tiempo en procesarse, y no se opone a que se almacenen en memoria caché, aplique ToList a la consulta. En escenarios habituales donde cada objeto se procesa solo una vez, el modelo de transmisión por secuencias es superior tanto en DataReader
como en LINQ to SQL.
Los detalles exactos de uso de la conexión dependen de lo siguiente:
Estado de la conexión si el DataContext se construye con un objeto de conexión.
Opciones de la cadena de conexión; por ejemplo, habilitar conjuntos de resultados activos múltiples (MARS). Para obtener más información, consulte Conjuntos de resultados activos múltiples (MARS).
Actualizaciones sin consultas
¿Puedo actualizar los datos de la tabla sin consultar primero la base de datos?
Aunque LINQ to SQL no posee comandos de actualización basados en conjuntos, puede utilizar cualquiera de las técnicas siguientes para actualizar sin consultar primero:
Utilice ExecuteCommand para enviar código SQL.
Cree una nueva instancia del objeto e inicialice todos los valores (campos) actuales que afectan a la actualización. A continuación, adjunte el objeto al DataContext utilizando Attach y modifique el campo que desee cambiar.
Resultados inesperados en la consulta
Mi consulta devuelve resultados inesperados. ¿Cómo puedo inspeccionar lo que está ocurriendo?
LINQ to SQL proporciona varias herramientas para inspeccionar el código SQL que genera. Una de las más importantes es Log. Para más información, consulte Soporte técnico para la Depuración.
Resultados inesperados del procedimiento almacenado
Tengo un procedimiento almacenado cuyo valor devuelto se calcula mediante `MAX()`. Cuando arrastro el procedimiento almacenado hasta la superficie del Diseñador O/R, el valor devuelto no es correcto.
LINQ to SQL proporciona dos maneras de devolver los valores generados por la base de datos a través de procedimientos almacenados:
Asignando un nombre al resultado de salida.
Especificando explícitamente un parámetro de salida.
El siguiente es un ejemplo de resultado incorrecto. Dado que LINQ to SQL no puede asignar los resultados, siempre devuelve 0:
create procedure proc2
as
begin
select max(i) from t where name like 'hello'
end
El siguiente es un ejemplo de resultado correcto que utiliza un parámetro de salida:
create procedure proc2
@result int OUTPUT
as
select @result = MAX(i) from t where name like 'hello'
go
El siguiente es un ejemplo de resultado correcto que asigna un nombre al resultado de salida:
create procedure proc2
as
begin
select nax(i) AS MaxResult from t where name like 'hello'
end
Para obtener más información, consulta Personalizar operaciones utilizando procedimientos almacenados .
Errores de serialización
Cuando intento serializar, obtengo el siguiente error: «El tipo 'System.Data.Linq.ChangeTracker+StandardChangeTracker'... no está marcado como serializable»
La generación de código en LINQ to SQL admite la serialización DataContractSerializer. No admite XmlSerializer o BinaryFormatter. Para obtener más información, vea Serialización.
Múltiples archivos DBML
Cuando tengo varios archivos DBML que comparten algunas tablas, obtengo un error del compilador.
Establece las propiedades Espacio de nombres del contexto y Espacio de nombres de la entidad de Object Relational Designer en un valor distinto para cada archivo DBML. Este enfoque elimina la colisión entre nombres o espacios de nombres.
Evitar el establecimiento explícito de valores generados por la base de datos al insertar o actualizar
Tengo una tabla de base de datos con una columna «DateCreated» que tiene como valor predeterminado `Getdate()` de SQL. Cuando intento insertar un nuevo registro utilizando LINQ to SQL, el valor queda establecido en NULL. Lo que esperaba es que tomara el valor predeterminado de la base de datos.
LINQ to SQL administra automáticamente esta situación para la identidad (incremento automático) y rowguidcol (GUID generado por base de datos) y para las columnas con marca de tiempo. En otros casos, debería establecer manualmente las propiedades IsDbGenerated=true
y AutoSync=Always/OnInsert/OnUpdate.
Múltiples DataLoadOptions
¿Puedo especificar opciones de carga adicionales sin sobrescribir la primera?
Sí. La primera no se sobrescribe, como se muestra en el ejemplo siguiente:
Dim dlo As New DataLoadOptions()
dlo.LoadWith(Of Order)(Function(o As Order) o.Customer)
dlo.LoadWith(Of Order)(Function(o As Order) o.OrderDetails)
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Order>(o => o.Customer);
dlo.LoadWith<Order>(o => o.OrderDetails);
Errores en el uso de SQL Compact 3.5
Obtengo un error cuando arrastro tablas fuera de una base de datos de SQL Server Compact 3.5.
El Object Relational Designer no admite SQL Server Compact 3.5, aunque el entorno de ejecución de LINQ to SQL sí. En esta situación, debe crear sus propias clases de entidad y agregar los atributos adecuados.
Errores en relaciones de herencia
Utilizo la herramienta de herencia incluida en el cuadro de herramientas del Object Relational Designer para conectar dos entidades, pero obtengo errores.
Crear una relación no es suficiente. Debe proporcionar información tal como la columna de discriminador, el valor de discriminador de la clase base y el valor de discriminador de la clase derivada.
Modelo de proveedor
¿Existe un modelo de proveedor público disponible?
No existe ningún modelo de proveedor público disponible. En este momento, LINQ to SQL solo admite SQL Server y SQL Server Compact 3.5.
Ataques mediante inserción de SQL
¿Cómo se protege LINQ to SQL de ataques de inyección de código SQL?
La inyección de código SQL ha sido un riesgo significativo para las consultas SQL tradicionales formadas mediante concatenación de los datos proporcionados por el usuario. LINQ to SQL evita esa inyección de código mediante el uso de SqlParameter en las consultas. Los datos proporcionados por el usuario se convierten en valores de parámetro. Este enfoque impide que se utilicen comandos malintencionados en los datos proporcionados por el cliente.
Cambiar la marca de solo lectura en archivos DBML
¿Cómo elimino los establecedores procedentes de algunas propiedades cuando creo un modelo de objetos a partir de un archivo DBML?
Siga estos pasos para este escenario avanzado:
En el archivo .dbml, modifique la propiedad cambiando la marca IsReadOnly a
True
.Agregue una clase parcial. Cree un constructor con parámetros para los miembros de solo lectura.
Revise el valor predeterminado de UpdateCheck (Never) para determinar si ése es el valor correcto para su aplicación.
Precaución
Si estás usando el Object Relational Designer en Visual Studio, tus cambios pueden sobrescribirse.
APTCA
¿Está System.Data.Linq marcado para que el código de confianza parcial pueda utilizarlo?
Sí, el ensamblado System.Data.Linq.dll se encuentra entre los ensamblados de .NET Framework marcados con el atributo AllowPartiallyTrustedCallersAttribute. Sin esta señal, los ensamblados incluidos en .NET Framework están destinados para su uso en código de plena confianza.
El principal escenario de LINQ to SQL para permitir llamadores que no son de plena confianza es habilitar el ensamblado de LINQ to SQL desde aplicaciones web, cuya configuración de confianza es Media.
Asignación de datos procedentes de varias tablas
Los datos de mi entidad proceden de varias tablas. ¿Cómo realizo la asignación?
Puede crear una vista en una base de datos y asignar la entidad a la vista. LINQ to SQL genera el mismo código SQL para vistas que para tablas.
Nota
El uso de vistas en este escenario presenta limitaciones. Este enfoque funciona de forma más segura cuando las operaciones realizadas sobre Table<TEntity> se admiten en la vista subyacente. Solo usted puede saber qué operaciones son las deseadas. Por ejemplo, la mayoría de las aplicaciones son de solo lectura, y otro número considerable realiza operaciones Create
/Update
/Delete
solo mediante procedimientos almacenados ejecutados contra vistas.
Agrupar conexiones
¿Existe una construcción que pueda ayudar al agrupamiento de DataContext?
No intente reutilizar instancias de DataContext. Cada DataContext mantiene el estado (incluida una caché de identidad) para una sesión de edición o consulta particular. Para obtener nuevas instancias según el estado actual de la base de datos, utilice un nuevo DataContext.
Puedes seguir utilizando agrupamiento de conexiones ADO.NET subyacente. Para obtener más información, vea Agrupación de conexiones de SQL Server (ADO.NET).
El segundo DataContext no resulta actualizado
Utilizo una instancia de DataContext para almacenar valores en la base de datos. Sin embargo, un segundo DataContext en la misma base de datos no refleja los valores actualizados. La segunda instancia de DataContext parece devolver valores almacenados en memoria caché.
Este comportamiento es así por diseño. LINQ to SQL continúa devolviendo los mismos valores o instancias que aparecen en la primera instancia. Cuando se realizan actualizaciones, se utiliza simultaneidad optimista. Los datos originales se utilizan para realizar una comprobación contra el estado de la base de datos actual a fin de comprobar que, de hecho, permanecen sin modificar. Si han cambiado, se produce un conflicto, y su aplicación deberá resolverlo. Una opción para su aplicación es restablecer el estado original al estado actual de la base de datos e intentar de nuevo la actualización. Para obtener más información, vea Cómo: Administrar confictos de cambios.
También puede establecer ObjectTrackingEnabled como falso, lo cual desactiva el almacenamiento en memoria caché y el seguimiento de cambios. A continuación, puede recuperar los últimos valores cada vez que realiza una consulta.
No se puede llamar a SubmitChanges en modo de solo lectura
Cuando intento llamar a SubmitChanges en modo de solo lectura, obtengo un error.
El modo de solo lectura desactiva la capacidad del contexto de realizar seguimiento de cambios.