Как работает кодирование с помощью LINQ? Что происходит за кулисами? - PullRequest
2 голосов
/ 07 мая 2009

Например:

m_lottTorqueTools = (From t In m_lottTorqueTools _
                     Where Not t.SlotNumber = toolTuple.SlotNumber _
                     And Not t.StationIndex = toolTuple.StationIndex).ToList

Какой алгоритм встречается здесь? Есть ли в фоновом режиме вложенный цикл for? Создает ли он хеш-таблицу для этих полей? Мне любопытно.

Ответы [ 3 ]

6 голосов
/ 07 мая 2009

Выражения запроса обычно переводятся в вызовы методов расширения. (Они не имеют , но в 99,9% запросов используется IEnumerable<T> или IQueryable<T>.)

Точный алгоритм того, что делает этот метод, варьируется от метода к методу. В вашем примере запроса не будут использоваться хеш-таблицы, но, например, используются операции объединения или группировки.

Простой вызов Where переводит что-то подобное в 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>) и вызывается для каждого элемента в последовательности. Результаты передаются в потоковом режиме, а выполнение откладывается - другими словами, ничего не происходит до тех пор, пока вы не начнете запрашивать элементы из результата, и даже тогда он будет делать столько, сколько нужно для обеспечения следующего результата. Некоторые операторы не откладываются (в основном те, которые возвращают одно значение вместо последовательности), а некоторые буферизуют ввод (например, Reverse должен прочитать до конца последовательности, прежде чем он сможет вернуть какие-либо результаты, потому что последний результат он читает первый, который он должен дать).

Боюсь, что выходит за рамки одного ответа - подробно описать каждого оператора LINQ, но если у вас есть вопросы по поводу конкретных, я уверен, что мы сможем вам помочь.

Я должен добавить, что если вы используете LINQ to SQL или другого провайдера, основанного на IQueryable<T>, все будет по-другому. Класс Queryable создает запрос (с помощью провайдера, который для начала реализует IQueryable<T>), и затем провайдер обычно переводит запрос в более подходящую форму (например, SQL). Точные данные (включая буферизацию, потоковую передачу и т. Д.) Будут полностью зависеть от поставщика.

1 голос
/ 07 мая 2009

У LINQ в целом лот происходит за кулисами. При любом запросе он сначала переводится в дерево выражений с использованием IQueryableProvider, и оттуда запрос обычно компилируется в код CIL, и генерируется делегат, указывающий на эту функцию, которую вы, по сути, используете при каждом вызове запроса. Это очень упрощенный обзор - если вы хотите прочитать отличную статью на эту тему, я рекомендую вам посмотреть Как работает LINQ - Создание запросов . Джон Скит также разместил на этом сайте хороший ответ на этот вопрос .

1 голос
/ 07 мая 2009

То, что происходит, зависит не только от методов, но и от используемого поставщика LINQ. В случае, когда возвращается IQueryable<T>, именно поставщик LINQ интерпретирует дерево выражений и обрабатывает его так, как ему нравится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...