c# entity-framework database-connection idisposable

c# - ¿Necesito forzar un Dispose después de una consulta LINQ?



entity-framework database-connection (6)

Acabo de hacer esta misma pregunta en Programmers.SE . Robert Harvey dio una gran respuesta.

En general, no es necesario usar el uso de declaraciones con contextos de datos de Entity Framework. Colecciones perezosas es una de las razones por las que.

Lo invito a leer la respuesta completa en Programmers.SE, así como los enlaces que proporciona Robert en la respuesta.

Mi DBA dice que hay demasiadas conexiones abiertas y él cree que es mi código en .net lo que las deja abiertas.

Estoy utilizando primero las consultas LINQ y el código EF.

Método de ejemplo:

public List<Stuff> GetStuff() { var db = new DBContext(); var results = db.stuff.toList(); return results; }

¿Necesito disponer del db var una vez que haya terminado? Mi entendimiento es que no necesité hacerlo en EF y LINQ. Indíqueme una documentación de Microsoft sobre la administración de la conexión en el código o las mejores prácticas para las conexiones LINQ / EF y db

Actualizar:

yo añadí

db.Connection.Close(); db.Dispose();

y todavía veo la conexión abierta en SQL después de que se ejecutaron las dos líneas. ¿Hay alguna razón por la que no se cierre cuando lo fuerzo a cerrarse?


Debes escuchar a tu DBA! Sí, utilice un using . No deje las conexiones abiertas innecesariamente. Debes conectarte, hacer negocios con la base de datos y cerrar esa conexión, liberándola para otro proceso. Esto es especialmente cierto en los sistemas de alto volumen.

Editar. Déjame explicarte más con mis propias experiencias aquí. En el procesamiento de bajo volumen, probablemente no sea un problema, pero es un mal hábito no deshacerse de algo explícitamente o no, envolverlo en un using cuando se implementa claramente IDisposable .

En situaciones de gran volumen, esto es solo pedir un desastre. El servidor Sql asignará tantas conexiones por aplicación (se puede especificar en la cadena de conexión). Lo que sucede es que los procesos pasarán el tiempo esperando a que las conexiones se liberen si no se cierran rápidamente. Esto generalmente conduce a tiempos de espera o puntos muertos en algunas situaciones.

Claro, puedes modificar la administración del servidor Sql y, por ejemplo, pero cada vez que ajustas una configuración, estás haciendo un compromiso. Debe considerar las copias de seguridad en ejecución, otras tareas en ejecución, etc. Por esta razón, un desarrollador inteligente escuchará las advertencias de su DBA. No siempre se trata del código ...


El marco de la entidad utiliza, por lo que sé, la agrupación de conexiones por defecto para reducir la sobrecarga de crear nuevas conexiones cada vez. ¿Se cierran las conexiones cuando cierras tu aplicación?

Si es así, podría intentar reducir el tamaño máximo de la agrupación en su cadena de conexión o deshabilitar la agrupación de conexiones por completo. Vea here una referencia de posibles opciones en su cadena de conexión.


Mira esto, aquí hay un protocolo estándar sobre cómo usar objetos IDisponibles. https://msdn.microsoft.com/en-us/library/yh598w02.aspx

Dice:

"Como regla general, cuando utiliza un objeto IDisponible, debe declararlo e instanciarlo en una declaración de uso".

Como tienen acceso a recursos no administrados, siempre debe considerar una declaración de "uso".


Por defecto, DbContext gestiona automáticamente la conexión por usted. Así que no deberías tener que llamar explícitamente a Dispose.

Publicación del blog sobre el tema: Link

Pero creo que no disponer puede causar problemas de rendimiento si está procesando muchas solicitudes. Debe agregar una declaración de uso para ver si está causando o no un problema en su caso.


Sí, si su método define una Unidad de Trabajo; No, si algo más primitivo. (PS, en algún lugar de su código debería definir una Unidad de Trabajo, y esa cosa debería estar envuelta en un using (var context = new DbContext()) {} o equivalente).

Y si pertenece a la escuela de pensamiento de que su DbContext es su Unidad de Trabajo, entonces siempre estará envolviendo a ese chico malo con un bloque de using : el almacenamiento en caché local de los datos que se obtuvieron durante la vida del contexto junto con el acto del método SaveChanges como una especie de transacción liviana, y su SaveChanges (sin llamar a SaveChanges ) es su Retroceso (mientras que su SaveChanges es su SaveChanges ).