Примеры Linq

В данной статье попробую привести элементарный примеры LINQ-запросов с использованием лямбда выражений.


Исходные данные:


using System.Collections.Generic;
using System.Linq;

        public class MyClass
        {
            public int ID { get; set; }
            public string Name { get; set; }
            public string Group { get; set; }
            public string SubGroup { get; set; }
            public int value { get; set; }
        }

        public class MyRefClass
        {
            public string ID { get; set; }
            public string Name { get; set; }
        }




public List<MyClass> ListOfMyClass = new List<MyClass>()
                {
                    new MyClass(){ID=1, Name="n1", Group="g1", SubGroup="s1", value=21},
                    new MyClass(){ID=2, Name="n2", Group="g1", SubGroup="s2",value=12},
                    new MyClass(){ID=3, Name="n3", Group="g1", SubGroup="s2",value=53},
                    new MyClass(){ID=4, Name="n4", Group="g2", SubGroup="s1",value=54},
                    new MyClass(){ID=5, Name="n5", Group="g2", SubGroup="s2",value=25},

                };

        public List<MyClass> ListOfMyClass2 = new List<MyClass>()
                {
                    new MyClass(){ID=6, Name="n6", Group="g3", value=41},
                    new MyClass(){ID=7, Name="n7", Group="g3", value=62},
                    new MyClass(){ID=8, Name="n8", Group="g4", value=13},
                    new MyClass(){ID=9, Name="n9", Group="g4", value=24},
                    new MyClass(){ID=10, Name="n10", Group="g4", value=85},
                };

        public List<MyRefClass> myRefClass = new List<MyRefClass>()
                {
                    new MyRefClass(){ID="g1", Name="Группа 1"},
                    new MyRefClass(){ID="g2", Name="Группа 2"},
                    new MyRefClass(){ID="g3", Name="Группа 3"},
                    new MyRefClass(){ID="g4", Name="Группа 4"}

                };


public List<MyRefClass2> myRefClass2 = new List<MyRefClass2>()
                {
                    new MyRefClass2(){ID="g1", SubID="s1", Name="Группа 1,1"},
                    new MyRefClass2(){ID="g1", SubID="s2", Name="Группа 1,2"},
                    new MyRefClass2(){ID="g2", SubID="s1", Name="Группа 2,1"},
                    new MyRefClass2(){ID="g2", SubID="s2", Name="Группа 2,2"}

                };

Отображение данных:

     <asp:Repeater runat="server" ID="rpr">
        <HeaderTemplate>
            <div style="width:100%">
                <div style="float:left;width:50px;">
                     Имя
                </div>
                <div style="float:left;width:50px;">
                     Группа
                </div>
                <div style="float:left;width:50px;">
                     Значение
                </div>
            </div>
            <br />
        </HeaderTemplate>
        <ItemTemplate>
            <div style="width:100%">
                <div style="float:left;width:50px;">
                     <%# Eval("Name")%>
                </div>
                <div style="float:left;width:50px;">
                     <%# Eval("Group")%>
                </div>
                <div style="float:left;width:50px;">
                     <%# Eval("value")%>
                </div>
            </div>
            <br />
        </ItemTemplate>
    </asp:Repeater>

protected void Page_Load(object sender, EventArgs e)
        {
            rpr.DataSource = ListOfMyClass;
            rpr.DataBind();
        }

Аналог на SQL:
SELECT Name, Group, value FROM ListOfMyClass

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass select item;



Просмотрим операции 
1. Фильтрация
     rpr.DataSource = ListOfMyClass.Where(w=>w.Group == "g1" & w.value>15);

Выбирает элементы, где группа равна "g1" и значение больше 15.

Аналог на SQL:
SELECT Name, Group, value FROM ListOfMyClass WHERE Group = 'g1' AND  value>15

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass where item.Group == "g1" &&  item.value >15 select item;
2. Сортировка
   rpr.DataSource = ListOfMyClass.OrderBy(o=>o.value);
или
   rpr.DataSource = ListOfMyClass.OrderByDescending(o=>o.value);

Сортирует элементы по возрастанию или убыванию значения

Аналог на SQL:
SELECT Name, Group, value FROM ListOfMyClass ORDER BY value 

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass orderby item.value select item;
или 
rpr.DataSource = from item in ListOfMyClass orderby item.value descending select item;




3. Выбор конкретных столбцов
   rpr.DataSource = ListOfMyClass.Select(s => new { Name = s.Name, Group = s.Group});

В результат попадают только два столбца "Name" и "Group"

Аналог на SQL:
SELECT Name, Group FROM ListOfMyClass

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass select new { Group = item.Group, Name = item.Name}; 


4. Объединение (Сложение)
   rpr.DataSource = ListOfMyClass.Union(ListOfMyClass2);

В результате получаем значения из двух множеств

Аналог на SQL:
SELECT Name, Group, value FROM ListOfMyClass
UNION
SELECT Name, Group, value FROM ListOfMyClass2


5. Присоединение
   rpr.DataSource = ListOfMyClass.Join(myRefClass, a => a.Group, b => b.ID, (a, b) => new { Name = a.Name, Group = b.Name, Value = a.value});

К нашему классу присоединяем "справочник" групп указываем по каким полям идёт объединение и какие поля выводим в результат. 

Аналог на SQL:
SELECT l.Name, g.Name, l.value FROM ListOfMyClass l
JOIN myRefClass g ON l.Group = g.ID

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass
          join item2 in myRefClass  on item.Group equals item2.ID

          select new { Group = item2.Name, Name = item.Name, value = item.value }; 





6. Группировка с агрегацией
  rpr.DataSource = ListOfMyClass.GroupBy(g => g.Group).Select(sg => new { Name = "-", Group = sg.Key, Value = sg.Sum(s=> s.value) });

Здесь идёт группировка по полу "Group", а в результат выводится название группы и сумма значений элементов группы.

Аналог на SQL:
SELECT '-', Group, SUM(value) FROM ListOfMyClass
GROUP BY Group

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass
                group item by new { item.Group} into g
                select new { Group = g.Key.Group, Name = "-", value = g.Sum(s=>s.value) }; 



7. Присоединение по нескольким ключам
    rpr.DataSource = ListOfMyClass.Join(myRefClass2, a => new { id1 = a.Group, id2 = a.SubGroup }, b => new { id1 = b.ID, id2=b.SubID }, (a, b) => new { Name = a.Name, Group = b.Name, Value = a.value });

Аналог на SQL:
SELECT l.Name, g.Name, l.value FROM ListOfMyClass l
JOIN myRefClass2 g ON l.Group = g.ID AND l.SubGroup = g.SubID

Аналог без лямбда выражений (Linq Query):
rpr.DataSource = from item in ListOfMyClass
           join item2 in myRefClass2 on new { item.Group, item.SubGroup } equals new { item2.ID, item2.SubID }

           select new { Group = item2.Name, Name = item.Name, value = item.value }; 


8. Взять первые несколько элементов
   rpr.DataSource = ListOfMyClass.Take(2);


В результате отобразятся первые два элемента 

Аналог на SQL:
SELECT TOP 2 Name, Group, value FROM ListOfMyClass



9. Взять все кроме нескольких первых
   rpr.DataSource = ListOfMyClass.Skip(2);

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

10. Не брать элементы пока, не выполнится условие, остальные попадают в выборку
  rpr.DataSource = ListOfMyClass.SkipWhile(w=>w.value <50);

В результате элементы будут пропускаться, пока не встретят value меньше 50. Остальные попадут в выборку. 

11. Брать пока выполнится условие, остальные не попадают в выборку
   rpr.DataSource = ListOfMyClass.TakeWhile(t=> t.value<50);

В результате элементы будут попадать в выборку, пока value меньше 50. Как только условие не выполнится - выборка останавливается.

12. Выполнить что-то для каждого элемента выборки
     List<string> str = new List<string>();
            ListOfMyClass.ForEach(f => f.Name = "ede");
            ListOfMyClass.ForEach(f => str.Add(f.Name));

 В первом случаи в список строк добавляются имена выборки, во втором - именам выборки присваивается значения "ede". Второй случай аналогичен команде UPDATE в SQL.

13. Получить первый элемент выборки
       string name = ListOfMyClass.FirstOrDefault().Name;
или
     string name = ListOfMyClass.First().Name;

 Получаем значение "Name" у первого элемента. Т.е. получим "n1"

14. Получить последний элемент выборки
       string name = ListOfMyClass.LastOrDefault().Name;
или
     string name = ListOfMyClass.Last().Name;

 Получаем значение "Name" у последнего элемента. Т.е. получим "n5"

Есть ещё множество функций (таких как сравнение, вычитание, проверки на единственность и существование) которые пока я здесь рассматривать не буду. Их можно интуитивно понять, если осознать предыдущие пункты.


Если есть вопрос как это применимо для SharePoint, то могу сказать, что это может быть, например,  полезно использовать для работы с элементами списка:


SPList list = web.Lists["st"];
List<SPListItem> listItems = list.Items.Cast<SPListItem>().ToList();

А далее уже применяем LINQ


Комментариев нет:

Яндекс.Метрика