2012-04-26 9 views
8

Usando entidad Código Marco primer lugar, tengo algo como:¿Por qué la configuración de EntityState en separado vacia una propiedad del tipo lista <T>?

public class Foo 
{ 
    public int Id { get; set; } 

    public List<Bar> Bars { get; set; } 
}  

Foo foo = (from f in ctx.Foos.Include("Bars") where f.Id == 42 select f).Single(); 

// At this point foo.Bars is populated 

ctx.Entry(foo).State = EntityState.Detached; 

// At this point foo.Bars is an empty List 

¿Por qué separar un objeto porque es propiedad public List<string> Bars, que fue incluido de forma explícita y con éxito, al ser vaciado?

¿Cuál es el procedimiento correcto para separar un objeto que puede tener muchas propiedades?

Respuesta

9

La razón por la cual la lista se vacía es una combinación de dos normas en Entity Framework:

  1. Al separar un objeto sólo este objeto en sí se separa sin los objetos propiedades de navegación lea.

  2. ObjectContext/DbContext no permite contener un gráfico de objeto que está parcialmente unido al contexto y parcialmente separado. Aunque esto puede ocurrir como un estado temporal al usar POCOs EF siempre arreglará este estado temporal al adjuntar automáticamente objetos separados en el gráfico dentro de varios métodos (como Add, Attach, establecer el estado de una entidad, etc.) o más reciente cuando SaveChanges se llama.

Esto significa que cuando se extrae el objeto raíz del contexto, EF se borrará la lista de los niños debido a que: a) los niños se mantienen unidas (regla 1), y b) una mezcla de objetos separados y unidos en el gráfico no está permitido (regla 2).

Por lo que puedo decir, no hay forma de separar un gráfico de objetos del contexto mientras se mantiene la estructura de árbol original. Puede separar al padre y luego a los hijos uno después del otro. Como resultado, ha separado todos los objetos del árbol del contexto, pero el árbol se destruye al mismo tiempo: cada propiedad de navegación queda anulada.

El objetivo principal de separar entidades manualmente es liberarlas para la recolección de elementos no utilizados en situaciones en las que tiene limitaciones de recursos de memoria y no desea y necesita mantener una gran cantidad de objetos en el contexto. Para este propósito, no importa que la estructura del gráfico se destruya.

No sé por qué necesita separar objetos del contexto. Pero tenga en cuenta que también existe la opción de cargar entidades de la base de datos sin asociarlas al contexto en primer lugar, como usar AsNoTracking().

Otra respuesta sobre el problema con algunas referencias a la documentación de MSDN está aquí: https://stackoverflow.com/a/7693732/270591

+0

El DbContext sale del ámbito mucho antes de que mi objetivo es siempre dispuesta. ¿La carga de mi objeto con 'AsNoTracking()' permitirá que se recopile el DbContext, o mi objeto aún mantendrá una referencia a él? Esa es mi principal preocupación. –

+0

@EricJ .: Primero está utilizando el código EF, por lo tanto, sus entidades son POCO. Si no utiliza la carga diferida (y parece que no lo hace porque 'Foo.Bars' no es' virtual'), entonces las entidades no son proxies y no tienen referencia al contexto. Entonces, la respuesta es sí, el contexto será basura recolectada incluso si todavía tiene una referencia a su entidad. – Slauma

+0

Si las entidades son proxies, entonces el contexto no será basura recolectada hasta que las entidades sean eliminadas. –

Cuestiones relacionadas