2010-10-15 28 views
6

Mam metodę, która zwraca grupę kontTyp zwrotu kolekcji z LINQ kwerendy

Public Shared Function GetAllNotesByUser(ByVal UserID As Guid) As Account (??) 
    Using db As New MyEntity 
     Dim query= (From A In db.Account _ 
        Where A.aspnet_Users.UserId = UserID _ 
        Select A) 
     Return query 
    End Using 
End Function 

bym wówczas jak przekazać to do innej funkcji do obliczania sumy dla wszystkich kont w kolekcji. Czy najlepiej jest zwracać niezliczoną, ogólną listę, po prostu nie jestem pewien, co działa najlepiej z LINQ i framework entity.

Odpowiedz

7

Podczas propagacji wyników zapytania LINQ metodami w ten sposób najlepszym wyborem dla typu zwrotu jest IEnumerable(Of T) dla LINQ do obiektów lub IQueryable(Of T) dla innych dostawców LINQ. W tym przypadku wygląda na to, że Account jest typem tak IEnumerable(Of Account) lub IQueryable(Of T) w zależności od rodzaju zapytania.

+1

najlepszym wyborem jest 'IEnumerable', chyba że najlepszym wyborem jest' IQueryable'. ;) –

+0

@Kirk, prawda. Zapomniałem o tej sprawie od non-LINQ do zapytań o obiekt – JaredPar

2

Najlepszy rodzaj byłoby

IEnumerable<Account> 

lub składni correspounding w VB: P

Właściwie wszystkie funkcje LINQ (.Where(), .Distinct() etc) są metody rozszerzenie do IEnumerable<T> i myślę, Dobrą praktyką jest kontynuowanie łańcucha w ten sam sposób.

+0

Szukałem MSDN, ale musi szukać w niewłaściwym miejscu. Skąd wiadomo, że WHERE() i Distinct() są metodami rozszerzenia IEnumerable . Nie pytam o ciebie, zastanawiam się, gdzie następnym razem będę miał podobne pytanie. –

+0

@Travis nie ma problemu. Właściwie w MSDN nie jest tak naprawdę "gdzie" zdefiniowane są te metody rozszerzenia ... ale można znaleźć listę na stronie 'IEnumerable ' (wersja ogólna): http://msdn.microsoft.com/ en-us/library/9eekhta0.aspx. Jest mała ikona, która mówi, że jest to metoda rozszerzenia ...a kiedy klikniesz na jedną z nich, możesz zobaczyć, w której przestrzeni nazw żyje ... To znaczy, aby użyć dowolnej metody rozszerzenia LINQ, musisz mieć 'using System.Linq;' na górze twojego pliku. – tsimbalar

+0

Aha, i sposób, w jaki to wiedziałem, to tylko dlatego, że VS zawsze dodaje odniesienie do "System.Linq", a Intellisense tylko sugeruje im :-). Behing the hood, wszystkie wyrazy podobne do "linq" są konwertowane na łańcuchy metod rozszerzenia Linq. – tsimbalar

0

Pytanie, które należy zadać, to: "Kiedy powinienem faktycznie wykonać SQL?" W LINQ jest to różnica między odroczonym a natychmiastowym wykonaniem. Każda metoda zwracająca wartość IEnumerable<> musi wykonać zapytanie, aby uzyskać wyniki. IQueryable<>, z drugiej strony, opóźnia wykonanie zapytania, dopóki nie zostanie wywołana metoda zwracająca wartość IEnumerable<>. W przykładzie, który podałeś, może być szybciej przekazać wynik funkcji GetAllNotesByUser jako IQueryable<>, tak aby uruchomić jedno zapytanie zamiast dwóch:

public static IQueryable<Account> GetAllNotesByUser(Guid UserId) 
{ 
    ... 
} 

Mogą zaistnieć sytuacje, w których trzeba wyliczyć wynik GetAllNotesByUser bez wykonywania dodatkowej manipulacji. W takich przypadkach pamiętaj, że możesz wywołać "ToList()", aby wymusić wykonanie zapytania.

var result = GetAllNotesByUser(<guid>).ToList(); 
+0

'AsEnumerable' nie wymusza wykonania zapytania: http://stackoverflow.com/questions/3389855/am-i-misunderstanding-linq-sql-asenumerable – nawfal

+0

Tak, masz rację. ToList() wymusi wykonanie. –

+0

Neil, a następnie edytuj swoją odpowiedź. Gwarantuje obniżenie cen w inny sposób :) – nawfal

1

Jest dobra odpowiedź here na IEnumerable<T> vs IQueryable<T>.

Chciałbym użyć IQueryable(Of T), jeśli chcesz dodatkowo ograniczyć zestaw w wywołującego metody, na przykład z klauzulą ​​WHERE. W przeciwnym razie użyłbym IEnumerable(Of T), jeśli wszyscy wywołujący zdają sobie sprawę, że muszą wykonać ToList() na wyniku, jeśli planują iterować go więcej niż jeden raz (w przeciwnym razie wykonalibyśmy wiele wywołań do bazy danych). Jeśli dzwoniący nie są świadomi, prawdopodobnie użyłbym ICollection(Of T) i wykonam ToList() w samej metodzie.