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

Odpowiedz Nowy wątek
2017-08-02 15:04

Rejestracja: 4 lata temu

Ostatnio: 2 lata temu

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 ;)

Pozostało 580 znaków

2017-08-02 16:18

Rejestracja: 13 lat temu

Ostatnio: 1 dzień temu

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.

Pozostało 580 znaków

2017-08-02 16:41

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

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/[...]-asp-net-mvc-and-web-api.aspx

Pozostało 580 znaków

2017-08-03 07:59

Rejestracja: 4 lata temu

Ostatnio: 2 lata temu

0

Dziękuję za pomoc :)

Pozostało 580 znaków

2017-08-03 08:21

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

Lokalizacja: Kraków

Hrypa napisał(a):

1) Moim zdaniem nie - wykonujesz asynchronicznie operację, na którą od razu czekasz; więc robisz to de facto synchronicznie.
3) 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.


It's easy to hate code you didn't write, without an understanding of the context in which it was written.
Ojej, to zmienia postać rzeczy. - boogi 2017-08-03 15:53

Pozostało 580 znaków

Odpowiedz

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

Robot: CCBot