LINQ to szeroki zestaw technologii opartych na (na przykład) składni rozumienia zapytań, na przykład:
var qry = from x in source.Foo
where x.SomeProp == "abc"
select x.Bar;
który jest mapowany przez kompilator na kod:
var qry = source.Foo.Where(x => x.SomeProp == "abc").Select(x => x.Bar);
i tu zaczyna się prawdziwa magia. Zauważ, że nie powiedzieliśmy, co Foo
tu jest - a kompilatorowi to nie przeszkadza! Tak długo, jak można go rozwiązać jakąś odpowiednią metodę o nazwie Where
, która może podjąć lambda, a wynik, który ma jakąś Select
metodę, która może przyjąć lambda, jest szczęśliwy.
Rozważmy teraz, że lambda można zestawiać zarówno w metodzie anonimowego (pełnomocnik, na LINQ-zadania, które obejmuje Linq do zestawu danych), lub do ekspresyjnym drzewa (model wykonania reprezentującą lambda modelu obiektowego ).
W przypadku danych w pamięci (zazwyczaj IEnumerable<T>
) po prostu wykonuje delegata - dobrze i szybko. Ale w przypadku IQueryable<T>
reprezentacji obiektowej wyrażenia (a LambdaExpression<...>
) może je rozdzielić i zastosować do dowolnego przykładu „LINQ-to-Something”.
W przypadku baz danych (LINQ-to-SQL, LINQ-to-Entities) może to oznaczać pisanie TSQL, na przykład:
SELECT x.Bar
FROM [SomeTable] x
WHERE x.SomeProp = @p1
Ale może to (na przykład w przypadku usług danych ADO.NET) oznaczać pisanie zapytania HTTP.
Wykonanie dobrze napisanego zapytania TSQL, które zwraca niewielką ilość danych, jest szybsze niż ładowanie całej bazy danych przez sieć, a następnie filtrowanie na kliencie. Oba mają jednak idealne scenariusze i po prostu błędne scenariusze.
Celem i zaletą jest umożliwienie używania pojedynczej, sprawdzanej statycznie składni do wykonywania zapytań w szerokim zakresie źródeł danych oraz uczynienia kodu bardziej wyrazistym (na przykład „tradycyjny” kod grupujący dane nie bardzo jasne pod względem tego, co próbuje zrobić - ginie w masie kodu).