Основы LINQ

LINQ (Language Integrated Query) — это специальный язык запросов для .NET Framework. Он позволяет выполнять запросы к объектам находящимся в памяти, в типизированной базе данных и в XML докумнте; LINQ, DLINQ XLINQ соответственно…Источник: http://www.gotdotnet.ru/LearnDotNet/DotNet30/441508.aspx
Что такое LINQ

LINQ (Language Integrated Query) — это специальный язык запросов для .NET Framework. Он позволяет выполнять запросы к объектам находящимся в памяти, в типизированной базе данных и в XML докумнте; LINQ, DLINQ XLINQ соответственно.

Этот язык интегрирован в Visual Studio “Orcas”, но так же он доступен как отдельное расширение для Visual Studio 2005.

На момент написания данной статьи, полностью LINQ поддерживают только два языка программирования: C# и Visual Basic.NET.

Рассмотрение LINQ хотелось бы начать с создания примеров, на которых будет показаны все преимущества LINQ при работе с массивами данных.

Создание проекта

Что бы начать рассмотрение LINQ необходимо иметь Visual Studio “Orcas”, так как данная статья написана с использованием Visual Studio “Orcas” CTP May 2007.

Создадим проект Console Application с использованием .NET Framework 3.5

Основы LINQ

Работа с простыми массивами данных

В первом примере работы с LINQ попробуем выполнять запрос к простым массивам данных.

Для этого в наш пример добавим метод работы с массивом чисел и обратимся к нему в методе Main:

public static void TestLinq1()
{
    //Определяем массив чисел
    int[] intMass = {1,2,3,4,5,6,7,8,9,10};
    //Выполняем запрос к массиву intMass и получим его элементы, которые больше 4, но меньше 8
    var liteMass =    from i in intMass
            where i > 4 && i < 8
                 select i;
    foreach (var val in liteMass)
        Console.WriteLine(val);
}

Результатом работы данного метода будут выведенные на консоль числа:
5

6

7

Теперь попробуем выполнить преобразование данных при получении результата. Для этого в разделе select запроса LINQ необходимо указать, что необходимо сделать с данными.

public static void TestLinq2()
{
    //Определяем массив чисел
    int[] intMass = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    //Выполняем запрос к массиву intMass и выполняем преобразование в объект  
    //содержащий два поля Value - число и
    //Enev значение boolean показывающее является ли число четным
    var liteMass =    from i in intMass
                select new {Value = i,Even= (i % 2==0)};
    foreach (var val in liteMass)
        Console.WriteLine("{0} - {1}", val.Value,val.Even);
}

После выполнения метода на консоль будет выведено:
1 — False

2 — True

3 — False

4 — True

5 — False

6 — True

7 — False

8 — True

9 — False

10 — True

Работа с массивами и коллекциями классов

После рассмотрения простых примеров работы с данными можно приступить к работе с коллекциями классов.

Для этого создадим класс Unit:

class Unit
{
    //Новая возможность C#3.0 автоматические свойства
    public int Id{get;set;}
    public string Name{get;set;}
    public string Type{get;set;}
}

После этого создадим методы для работы с массивом Unit:

/// <summary>
/// Метод для работы с массивом Unit
/// </summary>
public static void TestLinq3()
{
    //Определяем массив объектов Unit используя новую возможность C#3.0
    //инициализаторы классов
    Unit[] unitMass = {
        new Unit() { Id = 1, Name = "Unit1", Type = "Root" }
        ,new Unit() { Id = 2, Name = "Unit2", Type = "Child" }
        ,new Unit() { Id = 3, Name = "Unit3", Type = "Child" }
    };
    var childUnits =    from unit in unitMass
                       where unit.Type == "Child"
                       select unit;
    foreach (var unit in childUnits)
        Console.WriteLine("{0} - {1}", unit.Name, unit.Type);
}

Работа с коллекциями не отличается от работы с массивами, но необходимо помнить, что LINQ умеет работать только с типизированными коллекциями (Generic)

Extension Methods (расширение методов) в C # 3.0

Для того, что бы далее рассмотреть Standard Query Operators, необходимо уделить внимание новому функционалу который появился в Orcas — Extension Methods.

Extension Methods — это возможность добавлять новые методы без изменения класса объекта.

Например, используя Extension Methods, можно в класс Object (базовый класс .NET) добавить новый методы PrintMe:

using System;
namespace ExtensionMethods
{
    class Program
    {
        static void Main()
        {
            string myString = "Hi!";
            myString.PrintMe(2); //Используем Extension Method
        }
    }
    /// <summary>
    /// Класс в котором объявлены Extension Methods должен быть static
    /// </summary>
    public static class MyClass
    {
        /// <summary>
        /// Определяем Extension Method PrintMe
        /// </summary>
        public static void PrintMe(this object obj, int count)
        {
            for (int i = 0; i < count; i++)
            {
                Console.WriteLine(obj.ToString());
            }
        }
    }
}

Extension Method-ы объявляются в static классах, и как результат должны быть static. При объявлении данного метода, в передаваемых параметрах, необходимо использовать ключевое слово this, после которого идет тип, для которого создается Extension Method.

Standard Query Operators (Стандартные операторы запросов)

Standard Query Operators — это Extension methods (расширенные методы) которые находятся в классе System.Linq.Enumerable. Они расширяют функционал объектов, наследуемых от интерфейса IEnumerable.

Так как Standard Query Operator-ов довольно большое количество в данной статье, будут рассмотрены только некоторые из них. Для более подробного рассмотрения воспользуйтесь списком ссылок в конце статьи.

Оператор Take

Оператор Take возвращает количество элементов массива, начиная с первого.

Например:

static void TakeOperator()
{
    int[] fullMass = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; //Определяем массив из 10 чисел
    var takeMass = fullMass.Take(4); //Выбераем из массива первых 4 элемента
    foreach (var n in takeMass)
    {
        Console.WriteLine(n);
    }
}

Результат:
1

2

3

4
Оператор TakeWhile

Оператор TakeWhile выполняет то же самое, что и Take, только выбор заканчивается, когда перестает, выполняется определенное условие.

static void  TakeWhileOperator()  
{
    int[] fullMass = { 1, 2, 3, 4, 1, 2, 3, 8, 9, -1 }; //Определяем массив из 10 чисел
    var takeMass = fullMass.TakeWhile(i => i <= 3);
    //Выбераем из массива элементы,пока их значения    удовлетворяют условию <=3    
    foreach (var  num in takeMass)    
    {        
        Console.WriteLine(num    
    }  
}

Результат:
1

2

3

1
Оператор Skip

Оператор Skip, наоборот выдает все элементы, пропуская определенное количество начальных элементов массива.

static  void SkipOperator()
{
    int[] fullMass = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; //Определяем массив из 10 чисел
    var skipMass = fullMass.Skip(4); //Пропускаем первые 4 элемента
    foreach (var num in skipMass)
    {
        Console.WriteLine(num);
    }
}

Результат:
5

6

7

8

9

10
Оператор SkipWhile

Оператор SkipWhile выбирает все элементы массива, начиная с того, на котором условие перестало выполняться.

static  void SkipWhileOperator()
{
    int[] fullMass = { 1, 2, 3, 4, 5, 2, 3, 8, 9, 10 };//Определяем массив из 10 чисел
    var skipMass = fullMass.SkipWhile(i => i <= 4);//Пропуская элементы, пока выполняется условие
    foreach (var num in skipMass)
    {
        Console.WriteLine(num);
    }
}

Результат:
5

2

3

8

9

10
Оператор Reverse

Оператор Reverse, переворачивает исходный массив.

static void  ReverseOperator()
{
    int[] fullMass = { 1, 2, 3, 4, 5 };//Определяем массив из 10 чисел
    var reverseMass = fullMass.Reverse();//Переворачиваем массив
    foreach (var num in  reverseMass)
    {
        Console.WriteLine(num);
    }
}

Результат:
5

4

3

2

1
Заключение

В данной статье были обзорно рассмотрены некоторые нововведения в языке программирования C# 3.0, а так же были рассмотрены основы работы с LINQ и Standard Query Operators.

Ссылки

Scott Guthrie «Using LINQ with ASP.NET (Part 1)»

Scott Guthrie «New «Orcas» Language Feature: Extension Methods»

MSDN «101 LINQ Samples»

MSDN «The LINQ Project»

Standard Query Operators