Używanie async dla zapytań do bazy danych przez EF

0

Witam,
załóżmy, że mam metodę seriwsu jak poniżej, która pobiera z bazy danych jakieś dane na podstawie dostarczonego identyfikatora.

public async Task<DataViewModel> GetData(int id)
{
     DataViewModel model = null;
     int? dataId =  (await _db.MyTable.FirstOrDefaultAsync(x => x.id == id))?.id_data;

     if(dataId != null)
     {
          //tutaj bardzo skomplikowane zapytanie do db z użyciem pobranego wcześniej dataId
          //rezultat pakowany do model
     }
     return model;
}

oraz metodę kontrolera, która ogranicza się do tylko do zwrócenia do widoku wyniku otrzymanego z powyższej metody serwisu, coś a'la:

public async Task<ActionResult> GetForm(int id)
{
     var model = await _serwis.GetData(id);
     return View(model);
}

Moje pytania:

  1. Jest jakikolwiek sens używania FirstOrDefaultAsync() dla prostego i szybkiego zapytania, którego rezultat na dodatek jest wykorzystywany natychmiast linijkę niżej?
  2. Czy dobieranie się do pola id_data w sposób przedstawiony na listingu jest poprawny (chodzi mi o "opakowanie" await nawiasem).
  3. To "bardzo skomplikowane zapytanie" w if, powinno być asynchroniczne? Ostatecznie jak tylko się wykona natychmiast zostanie zwrócone więc - jeśli dobrze rozumiem ideę asynchroniczności - niczego nie ugram, bo niczego w "między czasie" i tak nie robię.

Z góry dziękuję za pomoc ;)

1
  1. Moim zdaniem nie - wykonujesz asynchronicznie operację, na którą od razu czekasz; więc robisz to de facto synchronicznie.
  2. Tak, cały nawias zwraca Ci rekord z tabeli.
  3. Masz rację, tak jak w 1. Odpalanie asychnronicznej informacji i natychmiastowe czekanie na wynik mija się z celem.
1

Co do 3 punktu pozwolę sobie się nie zgodzić
Możemy skorzystać z Cancel Tokena, który pozwala na anulowania zapytania / mapowania na obiekty.
Dość przydatne, jeżeli nie interesuje nas wynik poprzedniego zapytania, bo np.: user zmienił literkę, klikną w inne pole.

W linku więcej info https://www.davepaquette.com/archive/2015/07/19/cancelling-long-running-queries-in-asp-net-mvc-and-web-api.aspx

0

Dziękuję za pomoc :)

5
Hrypa napisał(a):
  1. Moim zdaniem nie - wykonujesz asynchronicznie operację, na którą od razu czekasz; więc robisz to de facto synchronicznie.
  2. Masz rację, tak jak w 1. Odpalanie asychnronicznej informacji i natychmiastowe czekanie na wynik mija się z celem.

Nie i jeszcze raz nie, to jest await, a nie wait, to są dwie różne rzeczy!, używając awaita my nie czekamy i nie blokujemy wątku, tylko wątek wraca do puli i może obsłużyć kolejne requesty i to jest właśnie zysk który osiągamy z asynchroniczności w aplikacjach webowych: nasza aplikacja jest w stanie obsłużyć więcej requestów w danym przedziale czasu.
Więc:
3) Jak najbardziej odpalenie asynchronicznej metedy która długa trwa i natychmiastowe awaitowane ma sens.

  1. Natomiast tutaj to zależy, bo największy narzut będzie stanowiło pewnie komunikowanie się z bazą, niż samo wykonanie tego polecenia, więc najlepiej to zmierzyć ile czasu zajmuje wersja asynchroniczna a ile synchroniczna, zwykle mało komu się to chce i dla spójności robi się tak jak w reszcie kodu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1