Си шарп метод join

Си шарп метод join

Соединение в LINQ используется для объединения двух разнотипных наборов в один. Для соединения используется оператор join или метод Join() . Как правило, данная операция применяется к двум наборам, которые имеют один общий критерий.

Оператор join

Оператор join имеет следующий формальный синтаксис:

from объект1 in набор1 join объект2 in набор2 on объект2.свойство2 equals объект1.свойство1

После оператора join идет выборка объектов из второй коллекции. После оператора on указывается критерий соединения — свойство объекта из второй выборки, а после оператора equals — свойство объекта из первой выборки, которому должно быть равно свойство объекта из второй выборки. Если эти свойства равны, то оба объекта попадают в финальный результат.

Например, у нас есть два класса:

record class Person(string Name, string Company); record class Company(string Title, string Language);

Класс Person представляет пользователя и хранит два свойства: Name (имя) и Company (компания пользователя). Класс Company представляет компанию и хранит два свойства: Title (название компании) и Language (основной язык программирования в компании)

Объекты обоих классов будет иметь один общий критерий — название компании. Соединим по этому критерию два набора этих классов:

Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var employees = from p in people join c in companies on p.Company equals c.Title select new < Name = p.Name, Company = c.Title, Language = c.Language >; foreach (var emp in employees) Console.WriteLine($" - ()"); record class Person(string Name, string Company); record class Company(string Title, string Language);
join c in companies on p.Company equals c.Title

объект p из списка people (то есть объект Person) соединяется с объектом c из списка companies (то есть с объектом Company), если значение свойства p.Company совпадает со значением свойства c.Title . Результатом соединения будет объект анонимного типа, который будет содержать три свойства. В итоге мы получим следующий вывод:

Tom - Microsoft (C#) Sam - Google (Go) Mike - Microsoft (C#)

Обратите внимание, что в массиве people есть объект new Person(«Bob», «JetBrains») , но в массиве компаний компании с именем «JetBrains» нет, соответственно он не попал с результат. Аналогично в списке people нет объектов Person, которые бы соотствовали компании new Company(«Oracle», «Java») .

Читайте также:  Typescript object key types

Метод Join

В качестве альтернативы можно было бы использовать метод Join() :

Join(IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector);

Метод Join() принимает четыре параметра:

  • второй список, который соединяем с текущим
  • делегат, который определяет свойство объекта из текущего списка, по которому идет соединение
  • делегат, который определяет свойство объекта из второго списка, по которому идет соединение
  • делегат, который определяет новый объект в результате соединения

Перепишим предыдущий пример с использованием метода Join:

Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var employees = people.Join(companies, // второй набор p => p.Company, // свойство-селектор объекта из первого набора c => c.Title, // свойство-селектор объекта из второго набора (p, c) => new < Name = p.Name, Company = c.Title, Language = c.Language >); // результат foreach (var emp in employees) Console.WriteLine($" - ()"); record class Person(string Name, string Company); record class Company(string Title, string Language);

GroupJoin

Метод GroupJoin() кроме соединения последовательностей также выполняет и группировку.

GroupJoin(IEnumerable inner, Func outerKeySelector, Func innerKeySelector, Func resultSelector);

Метод GroupJoin() принимает четыре параметра:

  • второй список, который соединяем с текущим
  • делегат, который определяет свойство объекта из текущей коллекции, по которому идет соединение и по которому будет идти группировка
  • делегат, который определяет свойство объекта из второй коллекции, по которому идет соединение
  • делегат, который определяет новый объект в результате соединения. Этот делегат получает группу — объект текущей коллекции, по которому шла группировка, и набор объектов из второй коллекции, которые сооставляют группу

Например, возьмем выше определенные массивы people и companies и сгуппируем всех пользователей по компаниям:

Person[] people = < new Person("Tom", "Microsoft"), new Person("Sam", "Google"), new Person("Bob", "JetBrains"), new Person("Mike", "Microsoft"), >; Company[] companies = < new Company("Microsoft", "C#"), new Company("Google", "Go"), new Company("Oracle", "Java") >; var personnel = companies.GroupJoin(people, // второй набор c => c.Title, // свойство-селектор объекта из первого набора p => p.Company, // свойство-селектор объекта из второго набора (c, employees) => new // результат < Title = c.Title, Employees = employees >); foreach (var company in personnel) < Console.WriteLine(company.Title); foreach(var emp in company.Employees) < Console.WriteLine(emp.Name); >Console.WriteLine(); > record class Person(string Name, string Company); record class Company(string Title, string Language);

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

Microsoft Tom Mike Google Sam Oracle

Метод GroupJoin, также как и метод Join, принимает все те же параметры. Только теперь в последний параметр — делегат передаются объект компании и набор пользователей этой компании.

Обратите внимание, что для компании «Oracle» в массиве people нет пользователей, хотя для нее также создается группа.

Аналогичного результата можно добитьс и с помощью оператора join:

var personnel = from c in companies join p in people on c.Title equals p.Company into g select new // результат < Title = c.Title, Employees = g >;

Метод Zip

Метод Zip() последовательно объединяет соответствующие элементы текущей последовательности со второй последовательностью, которая передается в метод в качестве параметра. То есть первый элемент из первой последовательности объединяется с первым элементом из второй последовательности, второй элемент из первой последовательности соединяется со вторым элементом из второй последовательности и так далее. Результатом метода является коллекция кортежей, где каждый кортеж хранит пару соответствующих элементов из обоих последовательностей:

var courses = new List < new Course("C#"), new Course("Java") >; var students = new List < new Student("Tom"), new Student("Bob") >; var enrollments = courses.Zip(students); foreach (var enrollment in enrollments) Console.WriteLine($" - "); record class Course(string Title); // учебный курс record class Student(string Name); // студент

Здесь метод Zip объединяет соответствующие элементы из списков courses и students. В результате создается новая коллекция, которая хранит набор кортежей. Каждый кортеж в ней имеет два элемента. Первый элемент из свойства First представляет объект текущей коллекции (в данном случае объект Course), а второй элемент (в свойстве Second) хранит объект второй последовательности (в данном случае объект Student). Консольный вывод:

Course < Title = C# >— Student < Name = Tom >Course < Title = Java >— Student

Источник

Операции Join (C#)

Соединение двух источников данных — это связь объектов в одном источнике данных с объектами, которые имеют общий атрибут в другом источнике данных.

Join является важной операцией в запросах, направленных на источники данных, отношения которых друг к другу нельзя отследить напрямую. В объектно-ориентированном программировании оно может означать корреляцию между немоделируемыми объектами, например такими, как обратное направление одностороннего отношения. Примером одностороннего отношения является класс Customer, имеющий свойство типа City (город), в то время как класс City не имеет свойства, которое является коллекцией объектов Customer (клиент). В случае наличия списка объектов City для поиска всех клиентов в каждом городе можно использовать операцию соединения.

На платформе LINQ представлены методы объединения Join и GroupJoin. Они выполняют эквисоединения, или соединения, которые сопоставляют два источника данных на основе равенства их ключей. (Для сравнения, Transact-SQL поддерживает операции соединения, отличные от оператора «равно», например оператор «меньше, чем».) В терминах реляционных баз данных Join реализует внутреннее соединение — тип соединения, в котором возвращаются только те объекты, у которых есть совпадения в другом наборе данных. Метод GroupJoin не имеет прямого эквивалента в терминах реляционных баз данных, но реализует надмножество внутренних соединений и левых внешних соединений. Левое внешнее соединение — это соединение, которое возвращает каждый элемент первого (левого) источника данных, даже если в другом источнике данных не имеется соответствующих элементов.

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

Два накладывающихся кольца, отображающие внешнее/внутреннее.

Методы

Имя метода Описание Синтаксис выражения запроса C# Дополнительные сведения
Join Join две последовательности на основании функций селектора ключа и извлекает пары значений. join … in … on … equals … Enumerable.Join

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

Join

В следующем примере предложение join … in … on … equals … используется для объединения двух последовательностей на основе конкретного значения.

class Product < public string? Name < get; set; >public int CategoryId < get; set; >> class Category < public int Id < get; set; >public string? CategoryName < get; set; >> public static void Example() < Listproducts = new List < new Product < Name = "Cola", CategoryId = 0 >, new Product < Name = "Tea", CategoryId = 0 >, new Product < Name = "Apple", CategoryId = 1 >, new Product < Name = "Kiwi", CategoryId = 1 >, new Product < Name = "Carrot", CategoryId = 2 >, >; List categories = new List < new Category < CategoryName = "Beverage" >, new Category < CategoryName = "Fruit" >, new Category < CategoryName = "Vegetable" >>; // Join products and categories based on CategoryId var query = from product in products join category in categories on product.CategoryId equals category.Id select new < product.Name, category.CategoryName >; foreach (var item in query) < Console.WriteLine($"- "); > // This code produces the following output: // // Cola - Beverage // Tea - Beverage // Apple - Fruit // Kiwi - Fruit // Carrot - Vegetable > 

GroupJoin

В следующем примере используется предложение join … in … on … equals … into … для объединения двух последовательностей на основе конкретного значения, а полученные совпадения для каждого элемента группируются.

class Product < public string? Name < get; set; >public int CategoryId < get; set; >> class Category < public int Id < get; set; >public string? CategoryName < get; set; >> public static void Example() < Listproducts = new List < new Product < Name = "Cola", CategoryId = 0 >, new Product < Name = "Tea", CategoryId = 0 >, new Product < Name = "Apple", CategoryId = 1 >, new Product < Name = "Kiwi", CategoryId = 1 >, new Product < Name = "Carrot", CategoryId = 2 >, >; List categories = new List < new Category < CategoryName = "Beverage" >, new Category < CategoryName = "Fruit" >, new Category < CategoryName = "Vegetable" >>; // Join categories and product based on CategoryId and grouping result var productGroups = from category in categories join product in products on category.Id equals product.CategoryId into productGroup select productGroup; foreach (IEnumerable productGroup in productGroups) < Console.WriteLine("Group"); foreach (Product product in productGroup) < Console.WriteLine($""); > > // This code produces the following output: // // Group // Cola // Tea // Group // Apple // Kiwi // Group // Carrot > 

См. также

  • System.Linq
  • Общие сведения о стандартных операторах запроса (C#)
  • Анонимные типы
  • Формулировка Join и запросов перекрестного произведения
  • предложение join
  • Join с помощью составных ключей
  • Объединение содержимого из файлов разных форматов (LINQ) (C#)
  • Упорядочение результатов предложения соединения
  • Выполнение пользовательских операций соединения
  • Выполнение групповых соединений
  • Выполнение внутренних соединений
  • Выполнение левых внешних соединений
  • Заполнение коллекций объектов из нескольких источников (LINQ) (C#)

Источник

Оцените статью