2017-01-11 31 views
5

Staram się zrozumieć coś ze śledzeniem zmian w FE6.Śledzenie zmian w strukturze obiektu po wywołaniu ToList()

Mam kod podobny do tego.

public class SomeClass 
{ 
    private List<User> _users; 
    private DAL _dal; 

    public void ProcessUsers() 
    { 
     _users = _dal.GetUsers(); 

     foreach(var u in users) 
     { 
      u.user.Comment = "This is a test"; 
     } 

     _dal.SaveChanges(); 
    } 
} 

Klasa DAL wygląda mniej więcej tak.

public class DAL 
{ 
    ... 
    private DataContext _context; // Assume that this is being newed up in a constructor. 

    public List GetUsers() 
    { 
     return _context.Users.ToList(); 
    } 

    public void SaveChanges() 
    { 
     _context.SaveChanges(); 
    } 
} 

Więc jak widać z kodu w metodzie ProcessUsers mamy listy użytkowników i jesteśmy modyfikując tę ​​listę.

Teraz wiem, że to działa, tak jak zawsze to robiłem, ale zawsze miałem wrażenie, że obiekty na liście (użytkownicy w tym przypadku) były odniesieniem do odpowiedniego obiektu w lokalnym programie DBSet kolekcja.

Po chwili namysłu nie jestem pewien, czy tak się dzieje, jak gdyby kontekst został usunięty, lista wciąż jest zapełniana i można nią manipulować (Po prostu tracimy możliwość przekazywania jej z powrotem do bazy danych bez dodatkowej pracy), więc z tej perspektywy elementy na liście muszą być kopiami elementów z kolekcji lokalnej DBSet ... ale w takim przypadku nie miałbym, gdyby manipulowanie obiektem na liście miało jakikolwiek wpływ na obiekt w bazie danych, ponieważ byłaby to kopia.

Podsumowując

Chodzi o to, co się dzieje, gdy zgłoszę ToList na DBSet iw jaki sposób zmienić śledzenie prac w tym przypadku? - Wiem, że to działa, ale myślę, że moje obecne rozumienie może być nieprawidłowe.

Odpowiedz

0

Musisz użyć context.TableName.Update(obejct), aby oznaczyć zaktualizowany obiekt. Następny zapisz zmiany za pomocą context.Savechanges(); Więc w przykładzie

public void ProcessUsers() 
{ 
    _users = _dal.GetUsers(); 

    foreach(var u in users) 
    { 
     u.user.Comment = "This is a test"; 
     _dal.Users.Update(u); 
    } 

    _dal.SaveChanges(); 
} 
+0

Cóż, nie, to jest mój punkt, kod, który napisałem nie jest uszkodzony, działa tak, jak jest. Chcę tylko zrozumieć, co robi ToList() w DBSet, teraz zakładam, że lista jest wypełniona odwołaniami do oryginalnych obiektów z kolekcji lokalnej dbset. Ale z tego, co przeczytałem, nie, są to kopie - jednak w takim przypadku śledzenie zmian nie zadziałałoby, a powyższy kod się nie udał. – D3vy

1

EF posiada kolekcję gdzie wszystkie oczekujące zmiany są śledzone (_context.ObjectStateManager, see here...). Co więcej, ładując obiekty za pomocą EF, dostajesz instancję proxy zamiast prawdziwej klasy jednostki. Korzystanie z tego serwera proxy EF to "wstrzykiwanie" kodu do instancji podmiotu, który aktualizuje informacje o śledzeniu zmian.

Po pozbyciu się kontekstu tracisz te informacje. Aby dodać istniejącą instancję obiektu do innego kontekstu, można użyć metody _context.Attach().

Urządzenie SaveChanges() przetwarza informacje o numerze _context.ObjectStateManager.

+0

Cześć, przepraszam Nie sądzę, że w moim pytaniu było jasne, wiem, jak działa śledzenie zmian, a kod w powyższym przykładzie działa. Przypuszczam, że pytam, kiedy wywołuję listę do bazy danych, co znajduje się na tej liście ... kopie elementów w dbSet lub odwołania do tych obiektów? Po odrobinie kopania i rozmawiania z innymi w pracy jestem dość pewny, że lista MUSI być wypełniona odniesieniami do zawartości dbSet, a nie kopii. – D3vy