Выражения запросов
переводятся как обычно в вызовы метода расширения. (Они не есть быть, но 99,9% запросов использовать IEnumerable<T>
or или IQueryable<T>
.) .)
Точный алгоритм того, что делает этот метод, варьируется от метода к методу. Образец запроса не будет использовать хэш-таблицы, но, например, выполняется соединения или операции группировки.
Простой Where
call translates to something like this in C# (using iterator blocks, which aren't available in VB at the moment as far as I'm aware): вызов переводится как-то вроде этого в C е (с помощью итератор блоков, которые не доступны в VB на данный момент, насколько я знаю):
public static IEnumerable<T> Where(this IEnumerable<T> source,
Func<T, bool> predicate)
{
// Argument checking omitted
foreach (T element in source)
{
if (predicate(element))
{
yield return element;
}
}
}
Предикат предоставляется в качестве делегата (или выражение дерева, если вы используете IQueryable<T>
) and is called on each item in the sequence. The results are streamed and execution is deferred - in other words, nothing happens until you start asking for items from the result, and even then it only does as much as it needs to in order to provide the next result. Some operators aren't deferred (basically the ones which return a single value instead of a sequence) and some buffer the input (e.g. ) и называется по каждому пункту в последовательности. Результаты транслируются, а выполнение откладывается - другими словами, ничего не происходит, пока вы не начнете запрашивать элементы из результата, и даже тогда это делает столько, сколько необходимо для того, чтобы обеспечить следующий результат. Некоторые операторы не откладываются (в основном те, которые возвращают одно значение вместо последовательности), а некоторые буфер ввода (например. Reverse
has to read to the end of the sequence before it can return any results, because the last result it reads is the first one it has to yield). должен прочитать до конца последовательности, прежде чем он может вернуть какие-либо результаты, потому что последний результат он читает это первый он должен уступить).
Это выходит за рамки единого ответа, чтобы дать подробную информацию о каждом операторе LIN, я боюсь, но если у вас есть вопросы о конкретных из них я уверен, что мы можем обязать.
Я хотел бы добавить, что если вы используете LIN' для S'L или другого поставщика, который основан на IQueryable<T>
, things are rather different. The , все совсем по-другому. Класс Queryable
class builds up the query (with the help of the provider, which implements создает запрос (с помощью поставщика, который реализует IQueryable<T>
to start with) and then the query is generally translated into a more appropriate form (e.g. SQL) by the provider. The exact details (including buffering, streaming etc) will entirely depend on the provider., чтобы начать с), а затем запрос, как правило, переводится в более подходящую форму (например, S'L) поставщиком. Точные детали (включая буферизацию, потоковую передачу и т.д.) будут полностью зависеть от поставщика.