Большинство приложений ориентированы на данные, однако большинство хранилищ данных представляют собой реляционные базы данных. На протяжении многих лет дизайнеры и разработчики создавали приложения на основе объектной модели.
Объекты отвечают за соединение компонентов, имеющих доступ к данным, — так называемый уровень доступа к данным (DAL). Здесь нам нужно учитывать три момента:
Все данные, необходимые приложению, не обязательно хранить в одном ресурсе. Этим ресурсом может быть реляционная база данных, бизнес-объект, файл XML или веб-сервер.
Доступ к объектам в памяти проще и дешевле, чем доступ к данным в базах данных и файлах XML.
Доступные данные не используются напрямую, а сбрасываются, сортируются, группируются, изменяются и т. д.
Поэтому было бы очень полезно, если бы существовали инструменты, которые могли бы легко интегрировать все виды данных с помощью всего лишь нескольких строк кода — инструменты, которые могли бы интегрировать данные из разных источников и выполнять базовые операции с данными.
Language Integrated Query (LINQ) — один из таких инструментов. LINQ — это расширение .NET Framework 3.5, а его язык управления делает запросы более похожими на объекты. Он определяет общий синтаксис и модель программы, которые позволяют нам использовать идиоматический синтаксис для поиска различных типов данных.
Связанные операции, такие как операции поиска, проекта, ссылки, группы, раздела, установки и т. д., могут использоваться в LINQ, а компиляторы C# и VB в .NET Framework 3.5 поддерживают синтаксис LINQ, что позволяет хранить данные конфигурации, не прибегая к АДО.НЕТ.
Например, чтобы запросить таблицу Consumers в базе данных Northwind с помощью LINQ на C#, код должен быть следующим:
var data = from c в dataContext.Customerswhere c.Country == «Испания» выберите c;
в:
Ключевое слово from логически последовательно проходит через каждую коллекцию.
Выражения, содержащие ключевое словоwhere, сравнивают каждый объект в коллекции.
Оператор select выберет сравниваемый объект, добавит его в список и вернет его.
Ключевое слово var используется для объявления переменных. Поскольку точный тип возвращаемого объекта неясен, это указывает на то, что информацию необходимо выводить динамически.
Инструкции запроса LINQ можно применять к любому классу, поддерживаемому данными, который наследуется от IEnumerable, где T может быть любым типом данных, например List<Book>.
Давайте посмотрим на пример, чтобы понять концепцию. В примере используется следующий класс: Book.cs.
public class Books {public string ID {get; set;} public string Title {get; set; public decimal Price {get; List<Books> list = new List<Books>(); list.Add(new Books { ID = "001", Title = "Программирование на C#", Цена = 634,76 млн, DateOfRelease = Convert.ToDateTime("2010-02-05") }); list.Add(new Books { ID = "002", Title = "Изучите Java за 30 дней", Price = 250,76m, DateOfRelease = Convert.ToDateTime ("15 августа 2011") }); list.Add(новые книги {ID = "003", Title = "Программирование в ASP.Net 4.0", Price = 700,00 м, DateOfRelease = Convert.ToDateTime("2011-02-05") }); Title = «VB.Net Made Easy», Цена = 500,99 млн, Дата выпуска = Convert.ToDateTime("2011-12-31") }); list.Add(new Books { ID = "005", Title = "Программирование на C", Price = 314,76m, DateOfRelease = Convert.ToDateTime("2010- 02-05") }); list.Add(new Books { ID = "006", Title = "Программирование в C++", Price = 456,76 млн, DateOfRelease = Convert.ToDateTime("2010-02-05") }); list.Add(new Books { ID = "007", Title = "Разработка базы данных", Price = 1000,76 млн, DateOfRelease = Convert.ToDateTime("2010-02-05") }); список; }}
Используйте этот класс на веб-странице, чтобы иметь простой элемент управления меткой для отображения названия книги. Метод Page_Load создает список книг и возвращает названия с помощью запроса LINQ:
общедоступный частичный класс simplequery: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<Books> book = Books.GetBooks(); var booktitles = from b in book select b.Title ( var title в заголовках книг) lblbooks.Text += String.Format("{0} <br />", title }};
При запуске веб-страницы тег отображает результаты запроса:
Выражение LINQ выше:
var booktitles = из b в книгах выберите b.Title;
Эквивалентно следующему оператору SQL:
ВЫБЕРИТЕ название из книг
Помимо операторов, используемых до сих пор, существует множество других операторов для выполнения предложений запроса. Давайте посмотрим на некоторые операторы и предложения.
«Предложение объединения» в SQL используется для объединения двух таблиц данных и отображения набора данных в столбцах, которые появляются в обеих таблицах данных. LINQ также может поддерживать эту функцию. Чтобы проверить это, добавьте в предыдущий проект еще один класс с именем Saledetails.cs:
общественный класс Salesdetails {public int sales {get; } public intpages {get; ID = "001", страницы = 678, продажи = 110000}, новые сведения о продажах { ID = "002", страницы = 789, продажи = 60000}, новые сведения о продажах { ID = "003", страницы = 456, продажи = 40000}, новые сведения о продажах { ID = "004", страницы = 900, продажи = 80000}, новые сведения о продажах { ID = "005", страницы=456, продажи = 90000}, новые сведения о продажах {ID = "006", страниц = 870, продаж = 50000}, новые сведения о продажах {ID = "007", страниц = 675, продаж = 40000}, }; return sd.OfType<Salesdetails>();
Добавьте код в функцию Page_Load для выполнения запроса к двум таблицам с использованием обработки предложения соединения:
protected void Page_Load(object sender, EventArgs e){ IEnumerable<Books> book = Books.GetBooks(); IEnumerable<Salesdetails> sales = Salesdetails.getsalesdetails(); var booktitles = from b in book join s в продажах по b.ID равно s.ID select new { Name = b.Title, Pages = s.pages }; booktitles) lblbooks.Text += String.Format("{0} <br />", title);}
Страница результатов отображается следующим образом:
Предложениеwhere позволяет добавлять в запрос условия фильтрации. Например, если вы хотите получить библиографии, содержащие более 500 страниц, вы можете изменить дескриптор в методе Page_Load, чтобы он выглядел следующим образом:
var booktitles = from b в книгах присоединяется к s в продажах по b.ID, равному s.ID, где s.pages > 500 select new { Name = b.Title, Pages = s.pages };
Оператор запроса возвращает только те столбцы, количество страниц которых превышает 500:
Эти предложения позволяют сортировать результаты запроса. Чтобы запросить название, номер страницы и цену книги и отсортировать их по цене, напишите следующий код в дескрипторе метода Page_Load:
var booktitles = из b в книгах присоединиться к s в продажах по b.ID равно s.ID orderby b.Price select new { Name = b.Title, Pages = s.pages, Price = b.Price};
Возвращаемый кортеж:
Предложение let позволяет определить переменную и присвоить ей значение, рассчитанное на основе данных. Например, чтобы рассчитать общую стоимость продаж на основе двух приведенных выше значений продаж, вам необходимо рассчитать ее следующим образом:
TotalSale = Цена книги * Продажи
Чтобы завершить это уравнение, добавьте следующий фрагмент кода в дескриптор метода Page_Load:
Предложение let позволяет определить переменную и присвоить ей значение, рассчитанное на основе данных. Например, чтобы рассчитать общую стоимость продаж на основе двух приведенных выше значений продаж, вам необходимо рассчитать ее следующим образом:
var booktitles = from b в книге присоединиться к s в продажах по b.ID равно s.ID let totalprofit = (b.Price * s.sales) select new { Name = b.Title, TotalSale = totalprofit};
Результаты запроса показаны ниже: