none
LINQ Объясните механику работы GroupJoin RRS feed

Ответы

  • Ну, в принице, требования к аргументам описаны в документации метода.

    Так как C# - статически-типизированный язык, к нему легко делать подсказки в IDE. Поэтому Visual Studio показывает все требования при вводе кода.

    Компилятор тоже выдаёт внятные ошибки. Достаточно прочитать их и исправить согласно документации.

    -----

    Попробую привести пример от себя. Допустим, у нас имеются классы:

    class Author
    {
        public int ID;
        public string Name;
    }
    
    class Book
    {
        public int ID;
        public int AuthorID;
        public string Title;
    }

    Авторы книг и сами книги. Между ними реализована связь (как в реляционных базах данных).

    Создадим и заполним коллекции авторов и книг:

    var authors = new List<Author> {
        new Author { ID=1, Name="Vasya" },
        new Author { ID=2, Name="Petya" },
        new Author { ID=3, Name="Kolya" }
    };
    
    var books = new List<Book> {
        new Book { ID=1, AuthorID=1, Title="Hacking Win" },
        new Book { ID=2, AuthorID=1, Title="Hacking MacOS" },
        new Book { ID=3, AuthorID=1, Title="Hacking Linux" },
        new Book { ID=4, AuthorID=2, Title="LINQ Cookbook" },
        new Book { ID=5, AuthorID=2, Title="SQL Cookbook" }
    };

    Вася является автором трёх книг, Петя - двух, у Коли пока ни одной.

    В синтаксисе запросов GroupJoin можно реализовать следующим образом:

    var query1 = from a in authors
                 join b in books
                 on a.ID equals b.AuthorID
                 into authorBooks
                 select authorBooks;

    Тут хорошо видно, что книги и авторы объединяются (join) по полям ID и AuthorID. После чего они группируются в authorBooks.

    В синтаксисе методов этот запрос будет выглядеть следующим образом:

    var query2 = authors.GroupJoin(
                     books,
                     a => a.ID,
                     b => b.AuthorID,
                     (b, authorBooks) => authorBooks);

    На мой взгляд, наглядность такой записи хуже.

    Обратите внимание, что в данном случае в самом конце из пары (b, authorBooks) не используется b.

    -----

    Где можно почитать обо всём этом? Так-то материалов много, всё я знать не могу; приведу то, что читал сам и считаю достойным.

    Книга "LINQ Карманный справочник", Албахари. Первая треть книги - самое оно для понимания механики запросов. Там описан конвейер linq, как по нему движутся запросы и данные.

    Есть бесплатная утилита LINQpad. К ней можно скачать множество примеров кода; в том числе там будет примеры разных группировок, объединений и пр. Правда, на английском. Она полезна тем, что может конвертировать синтаксис запросов в синтаксис методов. Запрос query2 я получил именно в ней из query1.

    Статья LINQ как шаг к функциональному программированию. Рекомендую её только в том случае, если есть хотя бы небольшие знания функциональных языков.

    -----

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

    var query3 = authors.GroupJoin(
                    books,
                    a => { Console.WriteLine("a: "+a.ID); return a.ID; },
                    b => { Console.WriteLine("b: "+b.AuthorID); return b.AuthorID; },
                    (b, authorBooks) => authorBooks);

    Здесь будут выводиться айдишники книг и авторов, когда они обрабатываются в запросе.

    Конкретно в данном случае от этого толку мало, но часто бывает, что это помогает разобраться, эффективен ли запрос.

    • Помечено в качестве ответа Энтомолог 15 февраля 2015 г. 17:35
    15 февраля 2015 г. 14:52

Все ответы

  • Не совсем понятно, что вы подразумеваете под словом "механика".

    Конечным результататом является одновременно объединение (Join) и группировка (Group).

    15 февраля 2015 г. 9:46
  • Какие требования предъявляются к аргументам метода? Что будет делать метод с аргументами, по шагам, когда я предоставлю ему все аргументы корректно и перечислю элементы результата?
    15 февраля 2015 г. 13:25
  • Ну, в принице, требования к аргументам описаны в документации метода.

    Так как C# - статически-типизированный язык, к нему легко делать подсказки в IDE. Поэтому Visual Studio показывает все требования при вводе кода.

    Компилятор тоже выдаёт внятные ошибки. Достаточно прочитать их и исправить согласно документации.

    -----

    Попробую привести пример от себя. Допустим, у нас имеются классы:

    class Author
    {
        public int ID;
        public string Name;
    }
    
    class Book
    {
        public int ID;
        public int AuthorID;
        public string Title;
    }

    Авторы книг и сами книги. Между ними реализована связь (как в реляционных базах данных).

    Создадим и заполним коллекции авторов и книг:

    var authors = new List<Author> {
        new Author { ID=1, Name="Vasya" },
        new Author { ID=2, Name="Petya" },
        new Author { ID=3, Name="Kolya" }
    };
    
    var books = new List<Book> {
        new Book { ID=1, AuthorID=1, Title="Hacking Win" },
        new Book { ID=2, AuthorID=1, Title="Hacking MacOS" },
        new Book { ID=3, AuthorID=1, Title="Hacking Linux" },
        new Book { ID=4, AuthorID=2, Title="LINQ Cookbook" },
        new Book { ID=5, AuthorID=2, Title="SQL Cookbook" }
    };

    Вася является автором трёх книг, Петя - двух, у Коли пока ни одной.

    В синтаксисе запросов GroupJoin можно реализовать следующим образом:

    var query1 = from a in authors
                 join b in books
                 on a.ID equals b.AuthorID
                 into authorBooks
                 select authorBooks;

    Тут хорошо видно, что книги и авторы объединяются (join) по полям ID и AuthorID. После чего они группируются в authorBooks.

    В синтаксисе методов этот запрос будет выглядеть следующим образом:

    var query2 = authors.GroupJoin(
                     books,
                     a => a.ID,
                     b => b.AuthorID,
                     (b, authorBooks) => authorBooks);

    На мой взгляд, наглядность такой записи хуже.

    Обратите внимание, что в данном случае в самом конце из пары (b, authorBooks) не используется b.

    -----

    Где можно почитать обо всём этом? Так-то материалов много, всё я знать не могу; приведу то, что читал сам и считаю достойным.

    Книга "LINQ Карманный справочник", Албахари. Первая треть книги - самое оно для понимания механики запросов. Там описан конвейер linq, как по нему движутся запросы и данные.

    Есть бесплатная утилита LINQpad. К ней можно скачать множество примеров кода; в том числе там будет примеры разных группировок, объединений и пр. Правда, на английском. Она полезна тем, что может конвертировать синтаксис запросов в синтаксис методов. Запрос query2 я получил именно в ней из query1.

    Статья LINQ как шаг к функциональному программированию. Рекомендую её только в том случае, если есть хотя бы небольшие знания функциональных языков.

    -----

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

    var query3 = authors.GroupJoin(
                    books,
                    a => { Console.WriteLine("a: "+a.ID); return a.ID; },
                    b => { Console.WriteLine("b: "+b.AuthorID); return b.AuthorID; },
                    (b, authorBooks) => authorBooks);

    Здесь будут выводиться айдишники книг и авторов, когда они обрабатываются в запросе.

    Конкретно в данном случае от этого толку мало, но часто бывает, что это помогает разобраться, эффективен ли запрос.

    • Помечено в качестве ответа Энтомолог 15 февраля 2015 г. 17:35
    15 февраля 2015 г. 14:52