Большинство приложений ориентированы на данные, однако большинство хранилищ данных являются реляционными базами данных. На протяжении многих лет дизайнеры и разработчики разрабатывали приложения на основе объектных моделей.
Объекты отвечают за подключение к компонентам доступа к данным, называемым уровнем доступа к данным (DAL). Здесь мы должны рассмотреть три момента:
-
Все данные, необходимые в приложении, не хранятся в одном источнике. Источником может быть база данных отношений, какой-либо бизнес-объект, файл XML или веб-служба.
-
Доступ к объекту в памяти проще и дешевле, чем доступ к данным из базы данных или файла XML.
-
Доступ к данным не используется напрямую, но должен быть отсортирован, упорядочен, сгруппирован, изменен и т. Д.
Все данные, необходимые в приложении, не хранятся в одном источнике. Источником может быть база данных отношений, какой-либо бизнес-объект, файл XML или веб-служба.
Доступ к объекту в памяти проще и дешевле, чем доступ к данным из базы данных или файла XML.
Доступ к данным не используется напрямую, но должен быть отсортирован, упорядочен, сгруппирован, изменен и т. Д.
Следовательно, если существует один инструмент, облегчающий доступ ко всем видам данных, который позволяет объединять данные из таких разнородных источников данных и выполнять стандартные операции обработки данных в несколько строк кода, это было бы очень полезно.
LINQ или Language-Integrated Query — такой инструмент. LINQ — это набор расширений .Net Framework 3.5 и его управляемых языков, которые задают запрос как объект. Он определяет общий синтаксис и модель программирования для запросов к различным типам данных с использованием общего языка.
Реляционные операторы, такие как операции Select, Project, Join, Group, Partition, Set и т. Д., Реализованы в LINQ, а компиляторы C # и VB в .Net Framework 3.5, которые поддерживают синтаксис LINQ, позволяют работать с настроенными данными. хранить без обращения к ADO.NET.
Например, при запросе таблицы Customers в базе данных Northwind с использованием запроса LINQ в C # код будет следующим:
var data = from c in dataContext.Customers where c.Country == "Spain" select c;
Куда:
-
Ключевое слово «from» логически просматривает содержимое коллекции.
-
Выражение с ключевым словом where оценивается для каждого объекта в коллекции.
-
Оператор «select» выбирает оцениваемый объект для добавления в возвращаемый список.
-
Ключевое слово ‘var’ предназначено для объявления переменных. Поскольку точный тип возвращаемого объекта неизвестен, это означает, что информация будет выведена динамически.
Ключевое слово «from» логически просматривает содержимое коллекции.
Выражение с ключевым словом where оценивается для каждого объекта в коллекции.
Оператор «select» выбирает оцениваемый объект для добавления в возвращаемый список.
Ключевое слово ‘var’ предназначено для объявления переменных. Поскольку точный тип возвращаемого объекта неизвестен, это означает, что информация будет выведена динамически.
Запрос LINQ может быть применен к любому переносящему данные классу, который наследуется от IEnumerable <T>, здесь T — это любой тип данных, например, List <Book>.
Давайте посмотрим на пример, чтобы понять концепцию. В примере используется следующий класс: Books.cs
public class Books { public string ID {get; set;} public string Title { get; set; } public decimal Price { get; set; } public DateTime DateOfRelease { get; set; } public static List<Books> GetBooks() { List<Books> list = new List<Books>(); list.Add(new Books { ID = "001", Title = "Programming in C#", Price = 634.76m, DateOfRelease = Convert.ToDateTime("2010-02-05") }); list.Add(new Books { ID = "002", Title = "Learn Java in 30 days", Price = 250.76m, DateOfRelease = Convert.ToDateTime("2011-08-15") }); list.Add(new Books { ID = "003", Title = "Programming in ASP.Net 4.0", Price = 700.00m, DateOfRelease = Convert.ToDateTime("2011-02-05") }); list.Add(new Books { ID = "004", Title = "VB.Net Made Easy", Price = 500.99m, DateOfRelease = Convert.ToDateTime("2011-12-31") }); list.Add(new Books { ID = "005", Title = "Programming in C", Price = 314.76m, DateOfRelease = Convert.ToDateTime("2010-02-05") }); list.Add(new Books { ID = "006", Title = "Programming in C++", Price = 456.76m, DateOfRelease = Convert.ToDateTime("2010-02-05") }); list.Add(new Books { ID = "007", Title = "Datebase Developement", Price = 1000.76m, DateOfRelease = Convert.ToDateTime("2010-02-05") }); return list; } }
Веб-страница, использующая этот класс, имеет простой элемент управления меткой, который отображает названия книг. Событие Page_Load создает список книг и возвращает заголовки с помощью запроса LINQ:
public partial class simplequery : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<Books> books = Books.GetBooks(); var booktitles = from b in books select b.Title; foreach (var title in booktitles) lblbooks.Text += String.Format("{0} <br />", title); } }
Когда страница выполняется, метка отображает результаты запроса:
Вышеуказанное выражение LINQ:
var booktitles = from b in books select b.Title;
Эквивалентно следующему SQL-запросу:
SELECT Title from Books
Операторы LINQ
Помимо используемых ранее операторов, есть несколько других операторов, которые реализуют все предложения запроса. Давайте посмотрим на некоторые операторы и предложения.
Предложение Join
«Предложение соединения» в SQL используется для объединения двух таблиц данных и отображает набор данных, содержащий столбцы из обеих таблиц. LINQ также способен на это. Чтобы проверить это, добавьте еще один класс с именем Saledetails.cs в предыдущем проекте:
public class Salesdetails { public int sales { get; set; } public int pages { get; set; } public string ID {get; set;} public static IEnumerable<Salesdetails> getsalesdetails() { Salesdetails[] sd = { new Salesdetails { ID = "001", pages=678, sales = 110000}, new Salesdetails { ID = "002", pages=789, sales = 60000}, new Salesdetails { ID = "003", pages=456, sales = 40000}, new Salesdetails { ID = "004", pages=900, sales = 80000}, new Salesdetails { ID = "005", pages=456, sales = 90000}, new Salesdetails { ID = "006", pages=870, sales = 50000}, new Salesdetails { ID = "007", pages=675, sales = 40000}, }; return sd.OfType<Salesdetails>(); } }
Добавьте коды в обработчик событий Page_Load для запроса обеих таблиц с помощью предложения join:
protected void Page_Load(object sender, EventArgs e) { IEnumerable<Books> books = Books.GetBooks(); IEnumerable<Salesdetails> sales = Salesdetails.getsalesdetails(); var booktitles = from b in books join s in sales on b.ID equals s.ID select new { Name = b.Title, Pages = s.pages }; foreach (var title in booktitles) lblbooks.Text += String.Format("{0} <br />", title); }
Полученная страница выглядит так:
Пункт Где
Предложение where позволяет добавлять некоторые условные фильтры в запрос. Например, если вы хотите видеть книги, в которых количество страниц превышает 500, измените обработчик события Page_Load на:
var booktitles = from b in books join s in sales on b.ID equals s.ID where s.pages > 500 select new { Name = b.Title, Pages = s.pages };
Запрос возвращает только те строки, где количество страниц превышает 500:
Orderby и Orderbydecending Пункты
Эти пункты позволяют сортировать результаты запроса. Чтобы запросить заголовки, количество страниц и цену книги, отсортированные по цене, напишите следующий код в обработчике события Page_Load:
var booktitles = from b in books join s in sales on b.ID equals s.ID orderby b.Price select new { Name = b.Title, Pages = s.pages, Price = b.Price};
Возвращенные кортежи:
Оговорка
Предложение let позволяет определить переменную и присвоить ей значение, рассчитанное по значениям данных. Например, чтобы рассчитать общую продажу из двух вышеупомянутых продаж, вам необходимо рассчитать:
TotalSale = Price of the Book * Sales
Для этого добавьте следующие фрагменты кода в обработчик событий Page_Load:
Предложение let позволяет определить переменную и присвоить ей значение, рассчитанное по значениям данных. Например, чтобы рассчитать общую продажу из двух вышеупомянутых продаж, вам необходимо рассчитать:
var booktitles = from b in book join s in sales on b.ID equals s.ID let totalprofit = (b.Price * s.sales) select new { Name = b.Title, TotalSale = totalprofit};
Полученная страница запроса выглядит так: