2016-08-12 15 views
5

Mam aplikację, która składa się z 2 części w momencieJak ... Wyświetlanie danych z bazy

  1. widza, który odbiera dane z bazy danych przy użyciu EF
  2. usługę, która manipuluje danymi z bazy danych w czasie wykonywania.

Logika za kulisami obejmuje niektóre projekty, takie jak repozytoria - dostęp do danych realizowany jest za pomocą jednostki pracy. Sam przeglądarka jest formą WPF z podstawowym ViewModel.

ViewModel zawiera ObservableCollection, które jest źródłem danych mojej przeglądarki.

Teraz pytanie brzmi - Jak mogę odzyskać dane z bazy danych co kilka minut? Zdaję sobie sprawę z dwóch następujących problemów:

  1. To nie jest moje ostatnie dane repozytorium „loading” - robi EF „inteligentne” rzeczy i pobiera dane z lokalnej pamięci podręcznej? Jeśli tak, jak mogę wymusić na EF ładowanie danych z bazy danych?
  2. Ponowne ustawienie całej ObservableCollection lub dodawanie/usuwanie obiektów z innego wątku/backgroundworker (z wywołaniem) nie jest możliwe. Jak mam to rozwiązać?

Dodam niektóre z mojego kodu w razie potrzeby, ale w tej chwili nie sądzę, że to w ogóle mogłoby pomóc.

Edit:

public IEnumerable<Request> GetAllUnResolvedRequests() { 
     return AccessContext.Requests.Where(o => !o.IsResolved); 
    } 

Ten kawałek kodu nie będzie otrzymywać najnowsze dane - edytować niektóre wiersze ręcznie (Set IsResolved true), ale ta metoda pobiera go mimo wszystko.

Edit2:

Properties after editing data manually in database

Data in the database

Edit3:

var requests = AccessContext.Requests.Where(o => o.Date >= fromDate && o.Date <= toDate).ToList(); 
     foreach (var request in requests) { 
      AccessContext.Entry(request).Reload(); 
     } 
     return requests; 

Ostatnie pytanie: Powyższy kod "rozwiązuje" problem - ale moim zdaniem nie jest czysty. Czy istnieje inny sposób?

+0

EF będzie ładować dane z bazy danych, a nie z pamięci podręcznej. Wygląda na to, że potrzebujesz asynchronicznej architektury pub/sub. –

+0

Dziękuję za odpowiedź, ale jeśli punkt przerwania tuż za zwrotem trafi wszystkie żądania (bez względu na to, czy zmieniłem je w db ręcznie (przed powrotem)) zawierają właściwość IsResolved z wartością false => Modyfikowanie danych podczas działania nie spowoduje wyniku w zaktualizowanych danych – C4p741nZ

Odpowiedz

1

Po uzyskaniu dostępu do obiektu w bazie danych jednostka jest buforowana (i śledzona w celu śledzenia zmian, które wykonuje aplikacja, do momentu określenia opcji AsNoTracking).
To ma pewne problemy (na przykład problemy z wydajnością, ponieważ zwiększa się pamięć podręczna lub widzisz starą wersję encji, która jest w twoim przypadku).
Z tych powodów podczas korzystania z EF powinieneś pracować z wzorem Jednostki pracy (tzn. Powinieneś stworzyć nowy kontekst dla każdej jednostki pracy).

Możesz zajrzeć do tego artykułu firmy Microsoft, aby zrozumieć, jak implementować wzór jednostki pracy. http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

W przypadku korzystania z opcji Przeładuj nie jest dobrym wyborem, ponieważ aplikacja nie jest skalowalna. Dla każdego ponownego załadunku robisz zapytanie do bazy danych. Jeśli potrzebujesz tylko zwrócić pożądane jednostki, najlepszym sposobem jest stworzenie nowego kontekstu.

public IEnumerable<Request> GetAllUnResolvedRequests() 
{ 
    return GetNewContext().Requests.Where(o => !o.IsResolved).ToList(); 
} 
+0

Ale tworzenie nowego Kontekstu za każdym razem, gdy Dostęp do metody jest - moim zdaniem - nie jest dobrą praktyką ... Czy stworzenie nowego Modułu Pracy nie byłoby lepszym rozwiązaniem? – C4p741nZ

+0

Masz rację, powinieneś stworzyć kontekst dla jednostki pracy. Problem tworzenia kontekstów w niewłaściwym miejscu polega na tym, że nie można dodawać ani aktualizować jednostek z różnych/mieszanych kontekstów. – bubi

0

Oto, co możesz zrobić.

Możesz zdefiniować zadanie (które działa na ThreadPool), które okresowo sprawdza bazę danych (należy wziąć pod uwagę, że okresowe pobieranie danych EF ma swój własny koszt).

I możesz zdefiniować SQL Dependency w zapytaniu, aby w przypadku zmiany danych można było powiadomić główny wątek o tym samym.

Powiązane problemy