2010-02-18 8 views
22

puede lanzar a alguien en su opinión acerca de ventajas/desventajas entre envolviendo el DataContext en una instrucción using o no en LINQ-SQL en función de factores como el rendimiento, la memoria el uso, la facilidad de codificación, lo que hay que hacer, etc.En LINQ-SQL, envolver el DataContext es una declaración utilizando - A favor En contra

actualización: en una aplicación particular, he experimentado que, sin envolver el DataContext en el uso de bloques, la cantidad de uso de la memoria siguió aumentando a medida que los objetos vivos no fueron lanzados para GC. Como en el ejemplo siguiente, si mantengo la referencia a la Lista de q objetos y tengo acceso a entidades de q, creo un gráfico de objetos que no se lanza 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 mantienen vivas

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

    return q.toList(); 

Gracias.

+2

Parece un duplicado de: http://stackoverflow.com/questions/821574/c-linq-to-sql-should-datacontext-be-disposed-using-idposable/821595 – devuxer

+0

Me gustaría saber la impacto en la memoria. – hIpPy

+0

similar a http://stackoverflow.com/questions/821574/c-linq-to-sql-should-datacontext-be-disposed-using-disposable/821595, gracias DanM. – hIpPy

Respuesta

12

Un DataContext puede ser costoso para crear, en relación con otras cosas. Sin embargo, si ha terminado y quiere que las conexiones se cierren lo antes posible, esto hará que eso también libere los resultados almacenados en caché del contexto. Recuerda que lo estás creando no importa qué, en este caso solo le estás diciendo al recolector de basura que hay más cosas gratis para eliminar.

DataContext está hecho para ser un objeto de uso a corto, lo utilizan, conseguir la unidad de trabajo realizado, salir ... eso es precisamente lo que está haciendo con un uso.

Así que las ventajas:

conexiones
  • más rápido cerradas
  • de memoria libre del dispose (objetos en caché en el contenido)

Desventaja - más código? Pero eso no debería ser un impedimento, estás usando using correctamente aquí.

Mire aquí en 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 utilizar using/.Dispose():

La respuesta corta; No, usted no tiene que hacerlo, pero usted debe ...

+2

Aparentemente, hemos escuchado cosas diferentes sobre la complejidad de crear un DataContext. –

+0

@James: aunque no es tan pesado ** en relación con otras cosas **, en mi aplicación actual es, con mucho, el elemento más pesado para poner en cola, es liviano, pero aún más pesado que tu objeto promedio. –

5

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

+0

Esta es la respuesta que recibí al hacer una pregunta similar en otro lugar.Básicamente, no duele y puede ayudar, pero probablemente no. – mark123

+3

@ mark123: Con solo una excepción, todos los IDisposable que cree, use y termine dentro de un solo método, deben consumirse en un bloque 'using'. De lo contrario, los autores no habrían elegido implementar 'IDisposable'. –

+0

Estoy de acuerdo. Siempre trata de hacerlo bien. Estaba pasando por un problema cuando estaba tratando de descubrir cómo usar un bloque de uso junto con permitir que un contenedor IoC (Castle Windsor) instanciara elementos de un repositorio. Mientras enfatizo el problema, me dijeron que el contenedor IoC maneja el Dispose(). Espero que sea correcto, ya que realmente tiene sentido. – mark123

4

Depende de la complejidad de tus Datos Capa. Si cada llamada es una simple consulta simple, cada llamada puede ser envuelta en el uso de "Like" en su pregunta y eso estaría bien.

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

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

aquí 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 
    } 
} 
1

En una aplicación particular, he experimentado que, sin envolver el bloque DataContext en using, la cantidad de uso de la memoria siguió aumentando a medida que los objetos vivos no fueron puestos en libertad para GC. Como en el ejemplo siguiente, si guardo la referencia al objeto List<Table> y acceso a las entidades de q, creo un gráfico de objetos que no se lanza 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 
} 

Teniendo en cuenta este ejemplo, no se puede disponer el DataContext porque todos los casos en Table variable de lista qs ** comparten el mismo DataContext. Después de Dispose(), acceder a la entidad en process(Table q) arroja un contexto de datos ya dispuesto excepción.

El ugly kluge, para mí, era eliminar todas las referencias de entidades para q objetos después del ciclo foreach. La mejor manera es, por supuesto, utilizar la declaración using.

Por lo que mi experiencia dice, yo diría usar la declaración using.

5
  1. La primera vez que DataContext obtiene el objeto de DB.
  2. La próxima vez que active una consulta para obtener el mismo objeto (mismos parámetros) .: Verá la consulta en un generador de perfiles pero su objeto en DataContext no será reemplazado por uno nuevo de DB.

Sin mencionar que detrás de cada DataContext está el mapa de identidad de todos los objetos que está pidiendo desde DB (no desea mantener esto).

idea completa de DataContext es unidad de trabajo con concurrencia optimista. Úselo para transacciones cortas (solo una presentación) y deseche.

La mejor forma de no olvidarse es usar().

Cuestiones relacionadas