2012-04-26 10 views
8

Korzystanie Entity Framework kod najpierw muszę coś takiego:Dlaczego ustawienie EntityState to Detached Empty Właściwość typu 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 

Dlaczego odłączenie obiektu bo to własność public List<string> Bars, który wyraźnie i skutecznie włączone, należy opróżnić?

Jaka jest prawidłowa procedura odrywania obiektu, który może mieć wiele właściwości?

Odpowiedz

9

Powodem lista jest opróżniany jest połączeniem dwóch zasad w Entity Framework:

  1. Kiedy odłączyć obiekt tylko ten sam obiekt jest odłączony bez żadnych właściwości obiektów nawigacyjnych dotyczą.

  2. Obiekt ObjectContext/DbContext nie pozwala na trzymanie wykresu obiektów, który jest częściowo dołączony do kontekstu i częściowo odłączony. Chociaż może się to zdarzyć jako stan tymczasowy podczas korzystania z POCO, EF zawsze będzie naprawiać ten stan tymczasowy, automatycznie dołączając odłączone obiekty na wykresie w ramach różnych metod (takich jak Add, Attach, ustawiając stan obiektu itp.) Lub najnowsze, gdy SaveChanges jest nazywany.

To oznacza, że ​​kiedy odłączyć obiekt korzeniowy z kontekstu, EF będzie wyczyścić listę dzieci, ponieważ: a) dzieciom pozostać podłączony (zasada 1) i b) mieszanka jednorodzinnych i przyłączonych obiektów wykres nie jest dozwolony (zasada 2).

O ile wiem, nie ma możliwości odłączenia wykresu obiektowego od kontekstu przy zachowaniu oryginalnej struktury drzewa. Możesz odłączyć rodzica, a następnie dzieci jeden po drugim. W wyniku tego oddzieliłeś wszystkie obiekty drzewa od kontekstu, ale drzewo zostanie zniszczone w tym samym czasie - każda właściwość nawigacji zostanie unieważniona.

Głównym celem ręcznego odłączania elementów jest ich zwolnienie do zbierania śmieci w sytuacjach, w których występują ograniczenia zasobów pamięci i nie ma potrzeby trzymania dużej ilości obiektów w kontekście. W tym celu nie ma znaczenia, że ​​struktura wykresu zostanie zniszczona.

Nie wiem, dlaczego trzeba odrywać obiekty od kontekstu. Należy jednak pamiętać, że istnieje również możliwość załadowania jednostek z bazy danych bez dołączania ich do kontekstu, na przykład za pomocą AsNoTracking().

Inna odpowiedź o problemie z pewnymi odniesieniami do dokumentacji MSDN jest tutaj: https://stackoverflow.com/a/7693732/270591

+0

DbContext wykracza poza zakres długo przed moim celem jest zawsze unieszkodliwić. Czy ładowanie mojego obiektu za pomocą funkcji 'AsNoTracking()' pozwala na zbieranie DbContext, czy mój obiekt nadal będzie utrzymywał odniesienie do niego? To moja główna sprawa. –

+0

@EricJ .: Najpierw używasz kodu EF, dlatego twoje jednostki to POCO. Jeśli nie używasz leniwego ładowania (i wygląda na to, że nie, ponieważ 'Foo.Bars' nie jest' wirtualny'), to encje nie są proxy i nie mają odniesienia do kontekstu. Tak więc odpowiedź brzmi "tak", kontekst będzie zbiorem śmieci, nawet jeśli nadal będziesz mieć odniesienie do twojego podmiotu. – Slauma

+0

Jeśli podmioty są serwerami proxy, to kontekst nie zostanie zebrany do czasu usunięcia encji? –

Powiązane problemy