Поделиться через


Операции проецирования

Проекцией называют операцию преобразования объекта в новую форму, которая часто состоит только тех его свойств, которые будут использоваться впоследствии.С помощью проекции можно создать новый тип, который формируется из каждого объекта.Можно проецировать свойство и выполнять над ним математические функции.Также можно проецировать исходный объект, не изменяя его.

Методы стандартных операторов запросов, которые выполняют проецирование, перечислены в следующем разделе.

Методы

Имя метода

Описание

Синтаксис выражения запроса C#

Синтаксис выражения запроса Visual Basic

Дополнительные сведения

Select

Проецирует значения, основанные на функции преобразования.

select

Select

Enumerable.Select

Queryable.Select

SelectMany

Проецирует последовательности значений, основанных на функции преобразования, а затем выравнивает их в одну последовательность.

Использование нескольких предложений from

Использование нескольких предложений From

Enumerable.SelectMany

Queryable.SelectMany

Примеры синтаксиса выражений запроса

Bb546168.collapse_all(ru-ru,VS.110).gifSelect

В следующем примере предложение select в C# или предложение Select в Visual Basic используется для проецирования первой буквы из каждой строки в списке строк.

        Dim words = New List(Of String) From {"an", "apple", "a", "day"}

        Dim query = From word In words 
                    Select word.Substring(0, 1)

        Dim sb As New System.Text.StringBuilder()
        For Each letter As String In query
            sb.AppendLine(letter)
        Next

        ' Display the output.
        MsgBox(sb.ToString())

        ' This code produces the following output:

        ' a
        ' a
        ' a
        ' d


            List<string> words = new List<string>() { "an", "apple", "a", "day" };

            var query = from word in words
                        select word.Substring(0, 1);

            foreach (string s in query)
                Console.WriteLine(s);

            /* This code produces the following output:

                a
                a
                a
                d
            */

Bb546168.collapse_all(ru-ru,VS.110).gifSelectMany

В следующем примере несколько предложений from в C# или предложений From в Visual Basic используются для проецирования каждого слово из каждой строки в списке строк.


        Dim phrases = New List(Of String) From {"an apple a day", "the quick brown fox"}

        Dim query = From phrase In phrases 
                    From word In phrase.Split(" "c) 
                    Select word

        Dim sb As New System.Text.StringBuilder()
        For Each str As String In query
            sb.AppendLine(str)
        Next

        ' Display the output.
        MsgBox(sb.ToString())

        ' This code produces the following output:

        ' an
        ' apple
        ' a
        ' day
        ' the
        ' quick
        ' brown
        ' fox


            List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };

            var query = from phrase in phrases
                        from word in phrase.Split(' ')
                        select word;

            foreach (string s in query)
                Console.WriteLine(s);

            /* This code produces the following output:

                an
                apple
                a
                day
                the
                quick
                brown
                fox
            */

Select или SelectMany

Задача обоих методов Select() и SelectMany() заключается в создании результирующего значения (или значений) из исходных значений.Select() создает один результат для каждого исходного значения.Таким образом, общий результат является коллекцией, имеющей то же количество элементов, что и исходная коллекция.SelectMany(), напротив, создает общий результат, содержащий соединенные подколлекции из каждого исходного значения.Функция преобразования, которая передается в качестве аргумента методу SelectMany(), должна возвращать перечисляемую последовательность значений для каждого исходного значения.Эти перечисляемые последовательности затем объединяются SelectMany(), чтобы создать одну большую последовательность.

Следующие два рисунка показывают принципиальные различия между действиями этих двух методов.В обоих случаях предполагается, что функция выбора (преобразования) выбирает массив цветов из каждого исходного значения.

На этом рисунке представлено, как Select() возвращает коллекцию, которая имеет то же количество элементов, что и исходная коллекция.

Концептуальная иллюстрация действия Select()

На этом рисунке показано, как SelectMany() объединяет промежуточные последовательности массивов в один конечный результат, содержащий все значения из промежуточных массивов.

График, отображающий действие SelectMany().

Bb546168.collapse_all(ru-ru,VS.110).gifПример кода

В следующем примере сравнивается действие Select() и SelectMany().Код создает "букет" из цветов путем захвата первых двух элементов из каждого списка имен цветов в исходной коллекции.В этом примере "одно значение", которое использует функция преобразования Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>), само является коллекцией значений.Этот требует дополнительного цикла foreach (For Each в Visual Basic) для перечисления каждой строки в каждой подпоследовательности.

Class Bouquet
    Public Flowers As List(Of String)
End Class

Sub SelectVsSelectMany()
    Dim bouquets = New List(Of Bouquet) From { 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"sunflower", "daisy", "daffodil", "larkspur"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"tulip", "rose", "orchid"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"gladiolis", "lily", "snapdragon", "aster", "protea"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"larkspur", "lilac", "iris", "dahlia"})}}

    Dim output As New System.Text.StringBuilder

    ' Select()
    Dim query1 = bouquets.Select(Function(b) b.Flowers)

    output.AppendLine("Using Select():")
    For Each flowerList In query1
        For Each str As String In flowerList
            output.AppendLine(str)
        Next
    Next

    ' SelectMany()
    Dim query2 = bouquets.SelectMany(Function(b) b.Flowers)

    output.AppendLine(vbCrLf & "Using SelectMany():")
    For Each str As String In query2
        output.AppendLine(str)
    Next

    ' Display the output
    MsgBox(output.ToString())

    ' This code produces the following output:
    '
    ' Using Select():
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

    ' Using SelectMany()
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

End Sub
class Bouquet
{
    public List<string> Flowers { get; set; }
}

static void SelectVsSelectMany()
{
    List<Bouquet> bouquets = new List<Bouquet>() {
        new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
        new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
        new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
        new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
    };

    // *********** Select ***********            
    IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

    // ********* SelectMany *********
    IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

    Console.WriteLine("Results by using Select():");
    // Note the extra foreach loop here.
    foreach (IEnumerable<String> collection in query1)
        foreach (string item in collection)
            Console.WriteLine(item);

    Console.WriteLine("\nResults by using SelectMany():");
    foreach (string item in query2)
        Console.WriteLine(item);

    /* This code produces the following output:

       Results by using Select():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia

       Results by using SelectMany():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia
    */

}

См. также

Задачи

Практическое руководство. Объединение данных с помощью LINQ с использованием соединений (Visual Basic)

Практическое руководство. Заполнение коллекций объектов из нескольких источников (LINQ)

Практическое руководство. Возвращение результата запроса LINQ в виде определенного типа (Visual Basic)

Практическое руководство. Разделение файла на несколько файлов с помощью групп (LINQ)

Ссылки

Предложение "select" (справочник по C#)

Предложение Select (Visual Basic)

System.Linq

Основные понятия

Общие сведения о стандартных операторах запроса