000173. C# введение в Linq

C# введение в Linq|Всем привет! Мы продолжаем изучать C# и в этом уроке мы будем знакомится в Linq.|wmysterio|wmysterio||||Это своего рода реализация языка запросов. Изначально планировалось использовать его с базами данных, но потом появилась возможность использовать запросы к любым коллекциям.

Результатом является выборка данных а команды для отбора этих данных - запросом. Синтаксис запроса может быть очень громоздким, однако ничего сложного в его написании нет. По крайней мере для меня.

Итак, преступим! Чтобы понять как это работает, напишем простой класс, например - Car:

cs
public class Car {

 public string Name { get; set; }
 public int Speed { get; set; }

 public Car( string Name, int Speed ) {
 this.Name = Name;
 this.Speed = Speed;
 }

}

Далее созданим случайное количество этих Car со случайными скоростями ( от 30 до 120, например ). Также, для работы с выборками нам нужно подключить пространство имём System.Linq:

cs
using System;
using System.Collections.Generic;
using System.Linq; // Подключаем пространство имён

namespace ConsoleApplication1 {

 class Program {

 static void Main( string[] args ) {

 List<Car> myCars = new List<Car>();
 var rnd = new Random();

 var count = rnd.Next( 5, 10 );

 for( int i = 0; i < count; i++ ) 
 myCars.Add( new Car( "Car " + i, rnd.Next( 30, 120 ) ) );
 
 Console.ReadKey();
 }

 }

 public class Car {

 public string Name { get; set; }
 public int Speed { get; set; }

 public Car( string Name, int Speed ) {
 this.Name = Name;
 this.Speed = Speed;
 }
 
 }

}

Далее нужно разобраться с синтаксисом запросов. В C# обычно начинается со слова from, которое указывает место, откуда выбирать данные. Далее идёт слово in - источник этих данных. Завершающим идёт слово select, после которого описывается формат выходных данных. Это может быть как отдельный параметр, так и их набор, сгруппированным анонимным типом. Общий вид запроса имеет следующий вид:

cs
from [ELEMENT] in [SOURSE] select [ELEMENT]
//из [ELEMENT] в [SOURSE] выбрать [ELEMENT]

Давайте построим запрос к нашему списку автомобилей и выберем все записи:

cs
var query = from car in myCars select car;

foreach( var item in query ) // выводим на экран результаты выборки
 Console.WriteLine( item.Name + " - " + item.Speed );

Остаётся вопрос - зачем это делать, если можно было просто пробежаться по циклу списка и вывести результат. Верно, так можно. Но представьте, на минуту, что нам нужно выбрать только некоторые данные, которые отвечают некому условию. Обычным способом пришлось бы создавать дополнительный список для хранения результата, что значительно увеличило наш код, особенно если мы имели дело с более крупным классом. К примеру, нам нужно выбрать все автомобили, скорость которых была бы больше 70. В запросах C# условием является ключевое слово where ( переводится как где ). Давайте напишем наш запрос заново:

cs
var query = from car in myCars 
 where car.Speed > 60 // пишем условие, при котором элемент попадёт в выборку
 select car;

foreach( var item in query )
 Console.WriteLine( item.Name + " - " + item.Speed );

При первом запуске у меня вывелся только 1 элемент из 5. После слова where ВСЕГДА должно идти выражение, которое возвращает тип bool. Запрос с условием можно описать так:

cs
from [ELEMENT] in [SOURSE] where [CONDITIONS] select [ELEMENT]
//из [ELEMENT] в [SOURSE] где [CONDITIONS] выбрать [ELEMENT]

Давайте усложним условие - скажем, чтобы выборка велать относительно некого диапазона скоростей автомобиля, например от 80 до 100. Наш запрос теперь будет иметь 2 слова where:

cs
var query = from car in myCars
 where car.Speed > 80
 where car.Speed < 100
 select car;

foreach( var item in query )
 Console.WriteLine( item.Name + " - " + item.Speed );

Давайте усложним задачу. Создадим второй список случайных Car:

cs
List<Car> myCars1 = new List<Car>();
List<Car> myCars2 = new List<Car>();
var rnd = new Random();

var count1 = rnd.Next( 5, 10 );
var count2 = rnd.Next( 3, 12 );

// Для лучшего понимания добавим приставку "Список 1" к имени авто в списке myCars1
for( int i = 0; i < count1; i++ ) 
 myCars1.Add( new Car( "Список 1: Car " + i, rnd.Next( 30, 120 ) ) );

// Для лучшего понимания добавим приставку "Список 2" к имени авто в списке myCars2
for( int i = 0; i < count2; i++ )
 myCars1.Add( new Car( "Список 2: Car " + i, rnd.Next( 20, 140 ) ) );

Пусть теперь перед нами стоит задача из двух списков выбрать элементы, скорость которых больше 60 и меньше 90:

cs
var query = from car in myCars1.Concat( myCars2 ) 
 where car.Speed > 60 && car.Speed < 90
 select car;

foreach( var item in query )
 Console.WriteLine( item.Name + " - " + item.Speed );

Поскольку типы myCar1 и myCar2 одинаковы, мы воспользовались методом Concat, который соединяет в одно целое два объекта. Далее всё как обычно :) Тема достаточно интересная, но настолько и сложная. В этом уроке я объяснил некоторые основные моменты использования запросов, однако существуют очень много методов. Написаны целые книги по теме Linq. Это очередная возможность языка C#, который делает его очень гибким и современным. Спасибо за внимание.|1157|1|0||c_vvedenie_v_linq|1511722782

Last updated