Вложенный «из» запроса LINQ, выраженный с помощью методов расширения
Как написать этот запрос LINQ с помощью синтаксиса метода расширения?
var query = from a in sequenceA from b in sequenceB select ...;
- Почему LINQ .Where (предикат) .First () быстрее, чем .First (предикат)?
- Как создать комбинации элементов из списка в .NET 4.0
- Удаление десериализации JSON в .NET-объект с использованием Newtonsoft (или LINQ to JSON, возможно?)
- Обновление свойства элемента в IEnumerable, но свойство не остается установленным?
- Как я могу разделить IEnumerable на группы IEnumerable
- Почему не поддерживаются методы расширения classа C #?
- Передача результата LINQ в ObservableCollection
- Преобразование DataTable в общий список в C #
- Имя динамической таблицы в linq
- List.Except не работает
- Объединение двух выражений (выражение <Func >)
- Группировать несколькими столбцами
- Как использовать LINQ Contains (string ) вместо Contains (string)
Для вашей будущей ссылки на все вопросы этой формы отвечает раздел 7.16 спецификации C #.
На ваш конкретный вопрос отвечает этот параграф:
Выражение запроса с предложением second from
блока, за которым следует предложение select
from x1 in e1 from x2 in e2 select v
переводится на
( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )
Таким образом, ваш запрос:
var query = from a in sequenceA from b in sequenceB select ...;
Такой же как
var query = ( sequenceA ) . SelectMany( a => sequenceB , ( a , b ) => ... )
(Обратите внимание, что, конечно, это предполагает, что «…» является выражением, а не, скажем, выражением, сопровождаемым продолжением запроса.)
Ответ hdv указывает, что
var query = ( sequenceA ) . SelectMany( a => ( sequenceB ) . Select( b => ... ) );
также будет логически обоснованным переводом, хотя это не перевод, который мы фактически выполняем. В первые дни реализации LINQ это был перевод, который мы выбрали. Однако, поскольку вы накладываете больше на предложения, это делает гнездо ягнят все более и более глубоким, что затем представляет компилятор с огромной проблемой в выводе типа. Этот выбор производительности компилятора сокращает количество переводов, поэтому мы внедрили прозрачный механизм идентификатора , чтобы дать нам гораздо более дешевый способ представить морскую среду глубоко вложенных областей.
Если эти предметы вас интересуют:
Для получения дополнительной информации о том, почему глубоко вложенные лямбды представляют трудную проблему для решения компилятора, см.
Для получения дополнительной информации о прозрачных идентификаторах см. Этот пост от Wes Dyer, который реализовал их в C # 3.0:
http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx
И моя серия статей о них:
http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/
var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...));
Редактировать : как отметил Эрик Липперт в комментариях, это дает те же результаты, но намеренно не так, как оно переведено внутренне. См. Его ответ на другой способ вызова SelectMany
, который соответствует оригиналу. Кроме того, для ясности добавлено опущенное b =>
.
Другой способ написать это:
var query = a.Join(b, i => new { }, j => new { }, (i, j) => new { i = i, j = j });