Вы находитесь на странице: 1из 29

ВВЕДЕНИЕ В LINQ

1. ВСТУПЛЕНИЕ.
Идеальный синтаксис:
var locals= f rom c i n customers
where c.ZipCode == 49000
se lec tnew
{
FullName = c.FirstName+ " "+ c.LastName ,
HomeAddress = c.Address
};

А таким запрос был на ранних этапах:


sequence< Cus tomer > l o ca l s= cus tomers.where (
Z ipCode == 49000
);
1.1. Лямбда-выражения.
Синтаксис C#2.0:
Пример с использованием анонимного метода:
I Enumerab le< Customer> locals=
EnumerableExtensions .Where (customers,
delegate(Customer c)
{
returnc.ZipCode == 49000 ;
}
);
Синтаксис C#3.0:
Возьмем предыдущий пример и заменим
анонимный метод лямбда-выражением:
I Enumerab le< Customer> locals=
EnumerableExtensions .Where (customers,
c => c.ZipCode == 49000 ) ;

Тип Customer выводится из сигнатуры метода


Where:
pub l i cs ta t i cIEnumerable< T> Where < T> (
IEnumerable< T> items, Func< T, boo l> predicate
)
1.2. Методы расширения.
Переписав Where в качестве метода расширения
мы получим:
I Enumerab le< Customer> locals= customers
.Where (c => c.ZipCode == 49000 ) ;

Теперь его сигнатура будет выглядеть примерно


так:
pub l i cs ta t i cIEnumerable< T> Where < T> (
th i sIEnumerable< T> items, Func< T, boo l> predicate
)
1.2. Методы расширения.
Переписав Where в качестве метода расширения
мы получим:
I Enumerab le< Customer> locals= customers
.Where (c => c.ZipCode == 49000 ) ;

Теперь его сигнатура будет выглядеть примерно


так:
pub l i cs ta t i cIEnumerable< T> Where < T> (
th i sIEnumerable< T> items, Func< T, boo l> predicate
)
Встроенные методы расширения для
IEnumerable<T>:
• Average — Среднее значение
• Concat — Соединение двух
последовательностей
• Count — Количество элементов
• Distinct — Уникальные элементы
• GroupBy — Группировка элементов
• Join — Соотношение двух последовательностей
• Max — Максимум
• Min — Минимум
• OrderBy — Сортировка элементов
• Select — Результирующая проекция
• Sum — Сумма
• Where — Фильтр на основе предиката
Используя метод Select изменим результирующую
проекцию:

I Enumerab le< string


> locals= customers
.Where (c => c.ZipCode == 49000 )
.Select(c => c.Name ) ;
Используя метод Select изменим результирующую
проекцию:

I Enumerab le< string


> locals= customers
.Where (c => c.ZipCode == 49000 )
.Select(c => c.Name ) ;
1.3. Анонимные типы.
Класс для проекции:
c lassCustomerTuple
{
pub l i cs t r i ngName ;
pub l i cs t r i ngAddress;

pub l i cCustomerTuple(s t r i ngname , s t r i ngaddress)


{
th i s.Name = name ;
th i s.Address = address;
}
}

Запрос:
I Enumerab le< Cus tomerTup le> locals= customers
.Where (c => c.ZipCode == 49000 )
.Select(c => new Cus tomerTup le(c.Name , c.Address) ) ;
Перепишем запрос с использованием анонимных
типов:
l o ca l s= cus tomers
.Where (c => c.Z ipCode == 49000 )
.Se lec t(c => new { c.Name , c.Address }) ;

На самом деле компилятором создается тип:


c lass
{
pub l i cs t r i ngName ;
pub l i cs t r i ngAddress;
}
Изменим имена полей анонимного типа:
l o ca l s= cus tomers
.Where (c => c.Z ipCode == 49000 )
.Se lec t(c => new {
Fu l lName = c.F i r s tName+ " "+ c.Las tName ,
HomeAddress = c.Address
}) ;

Полученный класс:
c lass
{
pub l i cs t r i ngFu l lName;
pub l i cs t r i ngHomeAddress ;
}
Изменим имена полей анонимного типа:
l o ca l s= cus tomers
.Where (c => c.Z ipCode == 49000 )
.Se lec t(c => new {
Fu l lName = c.F i r s tName+ " "+ c.Las tName ,
HomeAddress = c.Address
}) ;

Полученный класс:
c lass
{
pub l i cs t r i ngFu l lName;
pub l i cs t r i ngHomeAddress ;
}
1.4. Неявно типизированные локальные
переменные
Например:
var integer= 10;
var str= "Dog";
var sb = new StringBuilder
();

/ / Er ro r
i n teger= s t r;
Используем var для корректности синтаксиса
запроса:
var locals= customers
.Where (c => c.ZipCode == 49000 )
.Select (c => new {
FullName = c.FirstName+ " "+ c.LastName ,
HomeAddress = c.Address
}) ;

С помощью расширений языка C#3.0 этот запрос


можно переписать так:
var locals= f rom c i n customers
where c.ZipCode == 49000
se lec tnew {
FullName = c.FirstName+ " "+ c.LastName ,
HomeAddress = c.Address
};
2. АРХИТЕРКТУРА.
C#3.0 VB9 Другие

Классы .NET LINQ

LINQ to Google, LINQ to Flickr, LINQ to Smth.


Источники данных LINQ
LINQ to Objects LINQ to SQL LINQ to XML

<xml>
2.1. Интерфейс IEnumerable<T>.
Пример кода:
L i s<
t int> list
= new L i s <
t int> { 1, 3, 2 };

var query = f rom num i n list


where num < 3
se lec tnum ;

f o reach (var item i n query)


Conso le.WriteLine (item) ;

Интерфейс тут играет 2 важных роли:


• Источник данных list реализует IEnumerable<T>.
• Выражение запроса возвращает результат типа
IEnumerable<T>.
Пример компонуемости:
L i s<
t int> list
= new L i s <
t int> { 1, 3, 2 };

var query1 = f rom num i n list


where num < 3
se lec tnum ;

var query2 = f rom num i n query1


where num > 1
se lec tnum ;

var query3 = f rom num1 i n query1


f rom num2 i n query2
se lec tnum1 + num2 ;
3. РАСШИРЕНИЯ LINQ.
3.1. LINQ To Objects.
Используя реализацию базовыми коллекциями
интерфейса IEnumerable<T>, мы можем записать:
/ / Sor t i ng exmap le
i n t[]nums = new i n t[] {0, 4, 2, 6, 3, 8, 3, 1 };

var result= f rom n i n nums


nwhere
< 5
n
orderby
n;
se lec t

f o reach (i n tii n result


)
Conso le.WriteLine (i);
/ / Sum examp le
i n tsum = nums .Sum ();
Conso le.WriteLine(sum );

3.2. LINQ to SQL (DLINQ).


Сопоставление SQL-объектов и классов:

Database ↔ DataContext
Table ↔ Class
Column ↔ Property/Field
Relationship ↔ Property/Field
View ↔ Class
Stored Procedure ↔ Function
Зададимся таблицей:
CREATE TABLE [dbo].[Emp](
[Id] [int]
IDENT ITY(1,1) NOT NULL ,
[Name] [varchar](50) NULL ,
CONSTRA INT [PK_Emp] PR IMARY KEY CLUSTERED
(
[Id]ASC
) WITH (PAD_INDEX = OFF , IGNORE_DUP_KEY = OFF ) ON [PRIMARY]
) ON [PRIMARY]

Используем класс Employee для привязки:


[Table(Name = "dbo.Emp") ]
pub l i cc lassEmployee
{
Column
[ (IsDbGenerated = t rue, IsPrimaryKey= t rue) ]
pub l i ci n tId { get; se t; }
Column
[ ]
publicstringName { get; set; }
}
Выберем данные из БД, сортируя их по алфавиту:
DataContex t db =
new DataContex t(@"Data Source=PC-PDE\SQLEXPRESS;Integrated
Security=SSPI;Initial Catalog=test"
);

var sorted= f rom emps i n db.GetTable< Emp loyee > ()


orderby emps .Name ascend ing
se lec temps .Name ;

f o reach (s t r i ngemployee i n sorted)


Conso le.WriteLine (employee ) ;

Провайдеры SQL-LINQ:
• MS SQL Server — поддерживается по умолчанию.
• MySQL, Oracle, PostgreSQL — поддерживаются с
использованием стороннего провайдера DB_Linq.
3.3. LINQ TO XML (XLINQ).
Для работы с XML в XLINQ были созданы
специальные классы. Основные из них:

• XElement — XML-элемент
• XAttribure — XML-атрибут
Пример создания простого документа:
XE lement xml = new XE lement("contacts" ,
new XE lement("contact" ,
new XAt t r i bu te , "2") ,
("contactId"
new XE lement("firstName" , "Barry"),
new XE lement("lastName", "Gottshall" )
),
new XE lement("contact" ,
new XAt t r i bu te , "3") ,
("contactId"
new XE lement("firstName" , "Armando") ,
new XE lement("lastName", "Valdes" )
)
);
Создание документа из БД:
var xml = new XElement("employees",
f rom emps i n db.GetTable< Employee > ( )
orderbyemps .Name ascend ing
se lec tnew XElement("employee",
new XAttribute ("empId", emps .Id) ,
new XElement("lastName", emps .Name .Substring
(0,
emps .Name .IndexOf(' )') ) ,
new XElement("firstName" ,
emps .Name .Substring (emps .Name .IndexOf(' )'+ 1) )
)
);

Вам также может понравиться