Galin Iliev

Software Architecture & Development

LINQ to Objects

Ще започнем с LINQ to Objects, понеже останалите клонове са много подобни.

LINQ to Objects позволява на разработчиците да изпълняват „заявки” върху колекции от обекти, като разполагат със значителен набор от възможности, които могат да се очакват от  SQL заявка върху релационни бази данни.

При работа с колекции всеки програмист използва основно for и foreach цикли, за обхождане, if оператор за условие и т.н. LINQ ни освобождава от нуждата да пишем тези цикли.

Заявки може да се пишат срещу всяка колекция, която имплементира някой от следните интерфейси: IEnumerable, IEnumerable<T>, IQuerable.  Това на практите означава почти всички колекции, предоставени от .NET Framework. Например ако погледнем дефиницията на популярният списък List<T> ще видим какви интерфейси имплементира:

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

което на практика означава, че може да се пишат заявки към IList<T>.

С това се изчерпват изискванията към колекциите. А към обектите няма никакви специфични изисквания, за да може да се работи с тях с помощта на LINQ – това може да са струкури от .NET Framework или пък класове, които са дефинирани в нашите проекти – на практика всеки вид клас.

Може би е време да дадем пример, за да стане по-ясно!? Всъщност примерите, които разглеждахме до момента показват точно LINQ to Objects.

Нека все пак да разгледаме пример, в който колекцията от служители от точка Групиране с LINQ и C# 3.0 се  сортират според заплатата в низходящ ред:

var sorted = from e in employees

                         orderby e.Salary descending

                         select e;

 

foreach (Employee e in sorted) {

    Console.WriteLine("{0}\t\t{1}", e.Name, e.Salary);

}

И съответно резулата е:

Schumacher      1000000

July            2800

Galcho          2000

Joe             1800

Jana            900

Mary            700

Както казахме в началото това не единственият начин на изписване. Можем да постигнем същата цел като използваме разширяващите методи на IEnumerable<T>. В нашият случай трябва да използваме само метода IEnumerable<T>.OrderBy():

var sorted2 = employees.OrderBy(e => e.Salary);

Ако имаме и филтър освен сортирането може да се наложи да извикаме IEnumerable<T>.Where() и върху резултата IEnumerable<T>.OrderBy() последователно:

var sorted3 = employees.Where(e=>e.Name.StartsWith("G")).OrderBy(e => e.Salary);

Вътрешно LINQ заявката се преобразува до последователно извикване на разширяващи методи при LINQ to Objects. Затова няма разлика в резултата при двата начина на изпсиване, но LINQ заявката е по-добре читаем. При останалите клонове LINQ заявката се преобразува до подходяща заявка, в зависимост от конкретната реализация (напр. при LINQ to SQL се генерира SQL израз).

Както ще видим в следващите точки останалите клонове на LINQ се базират върху LINQ to Objects като добавят някаква функционалност.

 

Следваща част: LINQ to SQL

Content