Jak wymusić Entity Framework, aby zawsze pobierał aktualne dane z bazy danych?

86

Do wykonywania aktualizacji wsadowych używam biblioteki EntityFramework.Extended . Jedynym problemem jest to, że EF nie śledzi aktualizacji wsadowych wykonywanych przez bibliotekę. Więc kiedy pytam DbContextponownie, nie zwraca zaktualizowanych jednostek.

Odkryłem, że użycie AsNoTracking()metody podczas odpytywania wyłącza śledzenie i pobiera świeże dane z bazy danych. Jednak ponieważ EF nie śledzi jednostek, z AsNoTracking()którymi przeprowadzono zapytanie , nie mogę wykonać żadnej aktualizacji danych, których dotyczyło zapytanie.

Czy istnieje sposób, aby wymusić EF, aby uzyskać najnowsze dane podczas śledzenia zmian?

Saravana
źródło
2
29k poglądy i tylko 19 upvotes na tym ... no, w każdym razie dodałem kopalnię
jleach

Odpowiedzi:

148

Spróbuj tego, aby odświeżyć pojedynczą jednostkę:

Context.Entry<T>(entity).Reload()

Edycja: aby uzyskać świeże dane dla zbioru encji, warto spróbować pozbyć się DbContextinstancji po każdym żądaniu.

PlTaylor
źródło
Dziękuję Ci! Czy istnieje sposób na przeładowanie kolekcji jednostek zamiast jednej? Najlepiej w całości DbSet.
Saravana
Czy jest coś jeszcze, czego potrzebujesz, aby uznać to za odpowiedź?
PlTaylor
1
Tak, nadal nie pokazuje, jak ponownie załadować kolekcję jednostek.
Saravana
1
Czy próbowałeś pozbyć się swojego kontekstu dbcontext i utworzyć nowy?
PlTaylor
2
Dojście do tego wniosku zajęło mi wiele godzin. To EDYCJA w odpowiedzi pomogło mi znaleźć rozwiązanie. Dzięki!
BeemerGuy
17

Natknąłem się na to pytanie, szukając rozwiązania problemu, który miałem, w którym właściwości nawigacji nie wypełniały się po zaktualizowaniu jednostki. Za każdym razem, gdy próbowałem ponownie załadować jednostkę z bazy danych, pobierał on zamiast tego wpis z lokalnego magazynu, który nie wypełniłby właściwości nawigacji przez leniwe ładowanie. Zamiast niszczyć kontekst i odtwarzać go, odkryłem, że pozwoliło mi to uzyskać świeże dane przy działających serwerach proxy:

_db.Entry(entity).State = EntityState.Detached;

Logika, która się za tym kryła, polegała na tym, że moja aktualizacja dołączyła jednostkę, aby śledzić zmiany w niej. To dodaje go do lokalnego sklepu. Później wszelkie próby odzyskania jednostki z funkcjonalnymi serwerami proxy skutkowałyby przechwyceniem jednostki lokalnej zamiast wychodzenia do bazy danych i zwracania nowej jednostki obsługującej proxy. Wypróbowałem powyższą opcję przeładowania, która odświeża obiekt z bazy danych, ale to nie daje obiektu proxy z leniwym ładowaniem. Próbowałem zrobić Find(id), Where(t => t.Id = id), First(t => t.Id = id). Na koniec sprawdziłem dostępne stany, które zostały dostarczone i zobaczyłem, że jest stan „Odłączony”. Eureka! Mam nadzieję, że to komuś pomoże.

Zach
źródło
Gdzie stosujesz stan Detached, aby leniwe ładowanie działało? Wypróbowałem twoje rozwiązanie i nie zadziałało, muszę coś przeoczyć. Twoja pomoc byłaby doceniona
Rex
2
Rozgryzłem to: 1. zapisz jednostkę, 2. ustaw stan na odłączony, 3. odczytaj jednostkę z bazy danych. Dzięki za podpowiedź!
Rex
1

Uruchomienie kodu w tym samym kontekście nie przyniesie zaktualizowanych jednostek. Doda tylko nowe jednostki utworzone w bazie danych między uruchomieniami. Wymuszone przeładowanie EF można wykonać w następujący sposób:

ObjectQuery _query = Entity.MyEntity;
_query.MergeOption = MergeOption.OverwriteChanges;
var myEntity = _query.Where(x => x.Id > 0).ToList();
CodeMad
źródło
1

Zadeklarowałem zmienną encji, bez przypisania, jako część klasy. Pozwoliło mi to pozbyć się instancji bez utraty zmiennej dla odniesienia przez inne metody. Właśnie natknąłem się na to, więc nie ma zbyt wiele czasu wykonywania, ale jak dotąd wydaje się, że działa dobrze.

public partial class frmMyForm
{
    private My_Entities entity;

    public frmMyForm()
    {
        InitializeComponent();
    }

    private void SomeControl_Click(object sender, EventArgs e)
    {
        db.SaveChanges();
        db.Dispose();
        entity = new My_Entities();
        //more code using entity ...
}
Skuter
źródło
0

Dla mnie ... mam dostęp do mojego DbContext w następujący sposób:

_viewModel.Repo.Context

Aby zmusić EF do trafienia do bazy danych, robię to:

_viewModel.Repo.Context = new NewDispatchContext();

Zastępowanie bieżącego DbContext nowym wystąpieniem. Następnie następnym razem, gdy korzystam z usług danych, pobierają dane z bazy danych.

pdschuller
źródło