LINQ в C#
Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье мы поговорили про индексирующее свойство в C#. В данной статье я бы хотел поговорить про технологию LINQ в C#. LINQ (Language Integrated Query) — интегрированный язык запросов. Те, кто работал с базами данных, наверняка использовали SQL (Structured Query Language), который позволяет выполнять запрос к базе: извлекать данные из неё, изменять их, удалять. Особенностью SQL является то, что это декларативный язык.
Постараюсь пояснить: на SQL мы не описываем алгоритм, мы описываем результат, который хотим получить. Это очень удобно для работы с большими источниками данных. Это хорошо, когда у нас есть сервер базы данных, но что делать если у нас данные находятся в памяти в виде коллекции или массива. Допустим, мы создаём коллекцию людей (их имя и количество лет). Коллекция будет типа "Dictionary". Затем из данной коллекции мы хотим получить имена людей, чей возраст больше определенного заданного числа и заодно отсортировать людей по имени.
Конечно, это можно сделать просто: описать определенный алгоритм с циклом, который пробегает по всей коллекции и сравнивает возраст человека с тем числом, которое мы задали. В случае успеха эти люди добавляются в какую-то временную коллекцию. В данном случае хочется использовать тот же подход, что и с SQL.
LINQ как раз и позволяет декларативно написать запрос к различным источникам данных (коллекции, массивы).
Давайте на примере разберем, как использовать этот механизм:
Dictionary<string,int> myDictionary = new Dictionary<string,int>();
myDictionary.Add("Александр", 25);
myDictionary.Add("Петр", 35);
myDictionary.Add("Иван", 20);
myDictionary.Add("Семен", 15);
myDictionary.Add("Андрей", 5);
var result =
// myDictionary.Keys - коллекция ключей, в нашем случае имён
from string name in myDictionary.Keys
// здесь по ключу получаем значение, т.е. возраст
where myDictionary[name] > 18
// сортируем по имени (по ключу)
orderby name
select name;
foreach (string name in result)
Console.WriteLine(name); // Выйдет Александр, Иван, Петр
Поясню данный код. Сперва, я создаю коллекцию "Dictionary", в которую помещаю имя человека и его возраст (метод "Add"). "var result" — это переменная, в которой будет храниться результат нашего запроса. var обычно пишут, чтобы не задумываться о том, какой тип данных вернет LINQ-запрос.
Далее, как раз, начинается декларация того, что мы хотим получить. Очень сильно похоже на "SQL". Сразу обращу ваше внимание на то, что "select" ставится в конце. "name" — это имя, которое фактически будет использоваться, как переменная цикла.
Для того, чтобы код работал нужно подключить соответствующие пространства имён:
using System.Collections.Generic; using System.Linq;
Рассмотрим пример: необходимо получить имя самого младшего человека в коллекции.
var result2 = from string name in myDictionary.Keys orderby myDictionary[name] select name; string molodoi = result2.First<string>(); Console.WriteLine(molodoi); // выйдет Андрей
Для информации отмечу, что "LINQ" очень часто используется с "Entity Framework" для взаимодействия с объектной базой данных.
Реализуем какой-нибудь пример из жизни. Пусть имеется текстовый файл, в котором содержатся различные записи (1 строка — 1 запись). Необходимо получить список неуникальных записей, т.е. тех, которые повторяются. И эти повторяющиеся записи записать в отдельный файл.
try
{
string line = "";
// Создаём список, в котором будут храниться все имена из файла
List<string> listNames = new List<string>();
// Данная конструкция используется для того, чтобы по окончанию работы с файлом
// закрыть его.
using (StreamReader sr = new StreamReader(@"C:\not_unique_names.txt", Encoding.Default))
{
// Считываем файл построчно
while ((line = sr.ReadLine()) != null)
{
// Добавляем каждую строку в наш список listNames
listNames.Add(line.Trim());
}
}
// Находим список повторяющихся элементов
// Вся мощь LINQ в одной строке
// Хочу обратить внимание, что здесь мы уже используем методы
// Это ещё один подход для написания запросов LINQ
var uniqueListNames = listNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key);
// Записываем повторяющиеся элементы в файл
// false - файл будет каждый раз перезаписываться
using (StreamWriter sw = new StreamWriter(@"C:\repeted_names.txt", false, Encoding.Default))
{
foreach (string li in uniqueListNames)
{
sw.WriteLine(li);
}
}
Console.WriteLine("Нажмите клавишу для продолжения...");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Во время выполнения кода произошла ошибка: \n" + e.Message);
Console.ReadLine();
}
В данной статье вы узнали немного о том, как работать с LINQ в C#. Данных знаний должно хватить для того, что использовать этот механизм на практике.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.




