example linq linq-to-sql datacontext using

linq - example - datacontext c#



En LINQ-SQL, envolver el DataContext es una declaraciĆ³n que usa-pros contras (5)

Alguien puede expresar su opinión acerca de las ventajas y desventajas entre envolver el DataContext en una declaración de uso o no en LINQ-SQL en términos de factores como el rendimiento, el uso de la memoria, la facilidad de codificación, la acción correcta, etc.

Actualización : en una aplicación en particular, experimenté que, sin envolver el DataContext en el uso del bloque, la cantidad de uso de memoria seguía aumentando a medida que los objetos vivos no se lanzaban para GC. Como en, en el siguiente ejemplo, si mantengo la referencia a la lista de q objetos y entidades de acceso de q, creo un gráfico de objetos que no se publica para GC.

DataContext con el uso de

using (DBDataContext db = new DBDataContext()) { var q = from x in db.Tables where x.Id == someId select x; return q.toList(); }

DataContext sin usar y mantenido vivo

DBDataContext db = new DBDataContext() var q = from x in db.Tables where x.Id == someId select x; return q.toList();

Gracias.


  1. La primera vez que DataContext obtendrá el objeto de la base de datos.
  2. La próxima vez que inicie una consulta para obtener el mismo objeto (los mismos parámetros) .: ¡Verá la consulta en un generador de perfiles pero su objeto en DataContext no se reemplazará con uno nuevo de DB!

Por no mencionar que detrás de cada DataContext hay un mapa de identidad de todos los objetos que solicita desde la base de datos (no desea mantener esto alrededor).

La idea completa de DataContext es Unidad de trabajo con concurrencia optimista . Úselo para transacciones cortas (solo un envío) y deséchelo.

La mejor manera de no olvidar desechar es usando ().


Bueno, es una IDisposable , así que supongo que no es una mala idea. La gente de MSFT ha dicho que hicieron de DataContexts lo más ligero posible para que puedas crearlos con un abandono imprudente, así que probablemente no estés ganando mucho ...


Dependo de la complejidad de su capa de datos. Si cada llamada es una simple consulta, entonces cada llamada puede ajustarse en el uso de "Me gusta" en su pregunta y eso estaría bien.

Si, por otro lado, su capa de datos puede esperar múltiples llamadas secuenciales de la capa de negocios, terminaría creando / eliminando el DataContext repetidamente para cada secuencia más grande de llamadas. no es ideal.

Lo que he hecho es crear mi objeto Data Layer como IDisposible. Cuando se crea, se crea el DataContext (o en realidad, una vez que se realiza la primera llamada a un método), y cuando el objeto de la capa de datos se desecha, se cierra y se desecha el DataContext.

Esto es lo que parece:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Configuration; namespace PersonnelDL { public class PersonnelData : IDisposable { #region DataContext management /// <summary> /// Create common datacontext for all data routines to the DB /// </summary> private PersonnelDBDataContext _data = null; private PersonnelDBDataContext Data { get { if (_data == null) { _data = new PersonnelDBDataContext(ConfigurationManager.ConnectionStrings["PersonnelDB"].ToString()); _data.DeferredLoadingEnabled = false; // no lazy loading //var dlo = new DataLoadOptions(); // dataload options go here } return _data; } } /// <summary> /// close out data context /// </summary> public void Dispose() { if (_data != null) _data.Dispose(); } #endregion #region DL methods public Person GetPersonByID(string userid) { return Data.Persons.FirstOrDefault(p => p.UserID.ToUpper().Equals(userid.ToUpper())); } public List<Person> GetPersonsByIDlist(List<string> useridlist) { var ulist = useridlist.Select(u => u.ToUpper().Trim()).ToList(); return Data.Persons.Where(p => ulist.Contains(p.UserID.ToUpper())).ToList(); } // more methods... #endregion } }


En una aplicación en particular, experimenté que, sin envolver el DataContext en el using bloque, la cantidad de uso de memoria seguía aumentando a medida que los objetos vivos no se lanzaban para GC. Como en, en el siguiente ejemplo, si mantengo la referencia al objeto List<Table> y las entidades de acceso de q , creo un gráfico de objeto que no se publica para GC.

DBDataContext db = new DBDataContext() var qs = from x in db.Tables where x.Id == someId select x; return qs.toList(); foreach(q in qs) { process(q); // cannot dispose datacontext here as the 2nd iteration // will throw datacontext already disposed exception // while accessing the entity of q in process() function //db.Dispose(); } process(Table q) { // access entity of q which uses deferred execution // if datacontext is already disposed, then datacontext // already disposed exception is thrown }

Dado este ejemplo, no puedo disponer el datacontext porque todas las instancias de la Table en la variable de lista qs ** comparten el mismo datacontext . Después de Dispose() , el acceso a la entidad en process(Table q) arroja una excepción de datos ya dispuesta.

El kluge feo, para mí, fue eliminar todas las referencias de entidad para los objetos q después del bucle foreach. La mejor manera es, por supuesto, utilizar la instrucción using .

En lo que a mi experiencia se refiere, yo diría que use la instrucción using .


Un DataContext puede ser costoso de crear, en relación con otras cosas. Sin embargo, si ha terminado con él y quiere que las conexiones se cierren lo antes posible, esto lo hará, liberando también los resultados almacenados en caché desde el contexto. Recuerda que lo estás creando sin importar qué, en este caso, simplemente le estás avisando al recolector de basura que hay más cosas gratis para deshacerte de ellas.

DataContext está hecho para ser un objeto de uso breve, usarlo, hacer la unidad de trabajo, salir ... eso es precisamente lo que está haciendo con un uso.

Así que las ventajas:

  • Conexiones cerradas más rápidas
  • Memoria libre de la disposición (objetos en caché en el contenido)

Desventaja - ¿Más código? Pero eso no debería ser un factor disuasivo, lo estás using correctamente aquí.

Vea aquí la respuesta de Microsoft: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe

Versión corta de si necesita usar using / .Dispose() :

La respuesta corta; No, no tienes que hacerlo, pero deberías ...