Работа с данными в ASP.NET. Создание DAL (Data Access Layer)Источник: liveinternet
Предисловие автораЗа основу для данной статьи, я взял статью "Creating a Data Access Layer" (http://www.asp.net/learn/data-access/tutorial-01-cs.aspx) Я её попытался перевести, так как знания английского у меня не на самом хорошем уровне, но главное я понял как ОНО работает и попытаюсь об этом поведать вам. Буду придерживаться плана оригинальной статьи, но стиль написания местами поменяю. ВведениеВ задачи каждого web-разработчика входит работа с данными. Можно даже смело заявить, что это первостепенная задача программиста. Мы создаем базы данных для хранения информации, мы пишем скрипты и запросы для её грамотного извлечения, изменения или добавления, мы создаем сайты для её представления. Эта статья первая в своей серии "Работа с данными в ASP.NET", в которой я буду описывать различные техники работы с данными в ASP.NET. В данной статье я опишу процесс создания приложения, использующего Typed DataSets. Для изучения материала данной статьи вам необходимо иметь Microsoft SQL Server 2005 Express Edition или выше и базу данных Northwind, которую вы можете скачать с сайта Microsoft (http://www.microsoft.com/downloads/detail.aspx?FamilyId=06616212-0356-46A0-8DA2-EEBC53A68034&displaylang=en), также вам необходимо иметь на своем компьютере Microsoft Visual Studio, или хотя бы Microsoft Visual Web Developer Express (можно найти на сайте Microsoft) версии 2005 или 2008 (может и выше, по крайней мере на момент написания этой статьи у меня стоит Visual Web Developer Express 2008) Если у вас есть все необходимое, то наберитесь терпения и... Поехали! Первый шаг. Создание проекта и подключение к базе данныхДля того, чтобы нам создать наш Data Access Layer (DAL), нам необходимо создать проект в Visual Studio (или Visual Web Developer Express, здесь и далее просто VS). Для этого, откройте программу, перейдите в меню "File" и выберите пункт "New Web Site…". Укажите шаблон "ASP.NET Web Site", "Location: File System" и выберите произвольный путь, или если у вас установлен и настроен IIS, то "HTTP" (лично я делал вторым способом, как установить и настроить IIS я расскажу в другой раз, воспользуйтесь http://www.google.com/), и укажите используемый язык в C# ("Language: C#"). Рисунок SEQ Рисунок \* ARABIC 1. Создание ASP.NET приложения После нажатия на кнопку "OK", VS автоматически создаст проект, содержащий стартовую страницу Default.aspx и директорию App_Data. Теперь, когда сайт создан нам необходимо добавить к нему базу данных Northwind с помощью Server Explorer в VS. С помощью Server Explorer вы можете совершать манипуляции с базой данных, например, создавать, изменять или удалять таблицы, хранимые процедуры, представления и все это прямо в VS. Вы также можете просмотреть содержимое таблиц и создать собственные запросы, в том числе в графическом режиме, используя Query Builder. При создании TypedDataSet нам будет необходимо показать VS базу данных, по образу которой будет построен наш Typed DataSet. Добавление базы данных к проекту и подключение к нейВо введении я говорил, что для проекта нам необходима база данных Northwind, если вы еще её не скачали её или не установили, сделайте это сейчас. Для того, чтобы добавить базу данных в проект, откройте Solution Explorer (все указанные меню и утилиты находятся в меню "View"). Кликните правой кнопкой мыши по папке "App_Data" и выберите пункт "Add Existing Item…", в появившемся диалоговом окне укажите файл "NORTHWIND.MDF", у меня он лежал в директории "C:\SQL Server 2000 Sample Databases". Теперь откройте Server Explorer, в разделе Data Connections должна появиться база данных Northwind, если этого не произошло, то нажмите правой кнопкой мыши на пункте "Data Connecions" и выберите "Add Connection", в появившемся окне смените Data Source на "Microsoft SQL Server Database File (SqlClient)" и укажите местонахождение файла NORTHWIND.MDF. Нажмите "OK". Теперь у вас наверняка должна появиться база данных Northwind в списке Data Connections. Теперь вы можете посмотреть содержимое базы данных, таблиц, выполнить запросы и прочая, и прочая. Рисунок SEQ Рисунок \* ARABIC 2. База данных в Server Explorer Второй шаг. Создание Data Access LayerДля начала разберемся, что же такое Data Access Layer. Любое приложение, которое работает с данными, включает в себя так называемый уровень представления, в web-приложениях это страницы, которые показывают эти данные. Естественно, что для того, чтобы данные можно было представить, в прложении должна быть реализована логика обработки данных. В ASP.NET это может быть реализовано с помощью написания кода ADO.NET в страницах или использования элемента управления SqlDataSource или еще каким либо образом. В любом случае приложение будет содержать в себе логику доступа к данным. Рекомендуется логику доступа к данным вынести из уровня представления в отдельный - уровень доступа к данным, Data Access Layer (DAL). Все выгоды такого подхода очень хорошо описаны, в конце статьи я укажу ссылки на другие статьи, описывающие эти выгоды. Любой код, который осуществляет обработку данных, их выборку, изменение, команды SELECT, INSERT, UPDATE, и DELETE и прочие, должен находиться в DAL. Уровень представления не должен содержать в себе никакого кода обращения к базе данных, все данные в нем должны браться из DAL. База данных Northwind, взятая в качестве примера, содержит в себе такие таблицы, как Products и Categories, в которых хранится информация о товарах и о категориях, к которым они принадлежат. В нашем DAL мы должны описать следующие методы: · GetCategories(), который выдаст информацию обо всех существующих в базе данных категориях · GetProducts(), который выдаст информацию обо все существующих товарах · GetProductsByCategoryID(categoryID), который выдаст информацию обо всех продуктах, принадлежащих определенной категории · GetProductByProductID(productID), который выдаст информацию об определенном товаре Указанные методы выполнят подключение к базе данных, выполнят запрос и вернут полученный результат. То, в каком виде они вернут результат является очень важным! Эти методы могут вернуть стандартный DataSet или DataReader, заполненный данными из таблицы, но лучше будет, если они вернут strongly-typed objects (Если честно, не знаю как это переводится). A strongly-typed object is one whose schema is rigidly defined at compile time, whereas the opposite, a loosely-typed object, is one whose schema is not known until runtime. Например, DataReader или DataSet (используемый по умолчанию) имеют очень грубую структуру, т.к. она уже определена и при выполнении запроса такой объект просто заполняется результатом. Предположим мы имеем DataSet, в котором содержится результат какого-либо запроса. Для того чтобы этот результат получить мы должны обратится к нему кодом, вида DataTable.Rows[index]["ColumnName"]. Причем результат всегда имеет тип object. При обращении к нему мы должны использовать строковые и числовые "координаты". В другом же случае, таблица данных будет представлена в качестве объекта класса, где все столбцы таблицы будут определены как свойства класса, причем того же типа, в каком они определены в базе данных, а обращение примет вид DataTable.Rows[index].ColumnName. Для того, чтобы получать результаты в виде strongly-typed objects можно определить свой класс, в котором свойства будут отражать столбцы таблицы, а можно использовать Typed DataSet, который VS сделает сама. В данной статье мы будем использовать Typed DataSet. На следующем рисунке изображено взаимодействие между различными уровнями приложения при использовании Typed DataSet. Рисунок SEQ Рисунок \* ARABIC 3. Весь код по выборке и обработке данных возложен на DAL Создание Typed DataSet и DataTable AdapterДля того, чтобы создать наш собственный Typed DataSet, необходимо добавить его к проекту. Для этого кликните правой кнопкой мыши в ветке проекта в Solution Explorer и выберите "Add New Item…", в списке шаблонов выберите DataSet, и назовите его Northwind.xsd В открывшемся окне редактора щелкните правой кнопкой мыши в любом пустом месте и выберите Add/TableAdapter. Откроется мастер создания TableAdapter. Здесь я опустил описание, что такое TableAdapter. Смотрите оригинал статьи или используйте поиск. Перво-наперво вас попросят указать используемое подключение. Выберите NORTHWIN.MDF, если у вас его еще нет, тогда нажмите New Connection и создайте его. Теперь необходимо определить каким образом данные будут браться из базы и определить первый запрос на выборку данных. Укажите Use SQL statements Теперь необходимо ввести сам запрос. Его можно ввести вручную или использовать утилиту Query Builder. Введем запрос на выборку всех товаров из таблицы Products: В Query Builder"е это будет выглядеть так: После создания запроса на выборку, мастер предложит нам сгенерировать запросы на добавление, удеаление, редактирование записей в таблице. Что ж, не будем ему в этом препятствовать. И, напоследок, мастер предложит нам выбрать какие методы надо создавать и предложит ввести названия этих методов. Таким образом мы создали TableAdapter для таблицы Products. Реализовали два метода: Fill(), который позволит заполнить DataTable, переданную в качестве параметра, и метод GetProducts(), который вернет DataTable() после выполнения. А на экране мы увидим следующее: На данном этапе мы уже можем обратиться к объекту ProductTableAdapter, например таким кодом:
Как вы видите, в данном коде мы не написали не бита для обращения к базе данных, мы обращаемся толька к объекту DataTable, который нам любезно возвращает функция GetProducts(); причем мы эту DataTable можем использовать в качестве DataSource для, скажем, выпадающего списка. Ну вот и пришла пора привести конкретный пример! Для этого создадим страницу ASP.NET и назовем её AllProducts.aspx AllProducts.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="AllProducts.aspx.cs" Inherits="AllProducts" %>
AllProducts.aspx.cs using System; Результат будет следующим: Впечатляет? Но мы ведь не остановимся на этом? Шаг 3. Добавление в DAL запросов с параметромК этому моменту у нас есть только один запрос, который выводит все товары из таблицы. Разумеется нас это не всегда устроит, иногда необходимо извлечь только данные, которые отвечают определенному требованию. Сейчас мы создадим метод, который вернет нам все товары указанной категории - GetProductsByCategoryID(categoryID). Для этого кликнем по ProductsTableAdapter правой кнопкой мыши и выберем Add Query Далее я покажу скриншоты моих действий, так как вы уже один раз создали запрос, то описание действий не требуется. Если вы не знакомы с языком запросов SQL, то рекомендую вам его изучить, он не такой уж и сложный, как кажется. А на данном этапе мы указали, что нам нужны только товары WHERE CategoryID = @CategoryID, где @CategoryID - это параметр, который будет передаваться нашему методу в качестве аргумента Дадим имена нашему методу и сохраним запрос, нажав на Finish. В результате вы увидите следующее: Как вы видите у нас появился новый метод, который мы только что создали. Чтобы проверить его работоспособность, кликните по нему правой кнопкой мыши и выберите пункт Preview Data. Укажите в качестве параметра 1 и нажмите Preview Теперь создадим страницу Beverages.aspx, в которой выведем все товары, принадлежащие категории Beverages (Id = 1). Beverages.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Beverages.aspx.cs" Inherits="Beverages" %> Beverages.aspx.cs using System; Шаг 4. Добавление, изменение и удаление данныхСуществует два способа для того чтобы совершить эти три операции. Первый способ заключается в том, что в DAL описывается каждая из этих операций. Минус такого подхода в том, что для каждой операции над каждой записью нам необходимо выполнять отдельный запрос к базе данных Но есть и другой способ. Способ, когда физическое изменение данных в таблице происходит при помощи "слияния" DataSet, поскольку DataSet - это некое объектное представление таблицы, то вполне логично предположить, что можно просто удалить все данные из таблицы и вставить новые (измененные) из DataSet, так как DataSet полностью копирует данные таблицы. Это конечно не совсем так, но для первого раза я думаю хватит, чтобы понять... Итак, мы воспользуемся вторым способом. Как вы видите, мы можем совершить любые операции на DataTable, а потом внести изменения в базу данных всего лишь одной строчкой. Супер, правда? Но для начала нам необходимо разобраться в функциях добавления, изменения и удаления. Откройте Properties для ProductsTableAdapter, там вы увидите реализацию всех запросов: Чтобы изменить текст запроса, откройте свойство CommandText и откроется Query Builder Приведу пример использования этих трех методов Задача такова: необходимо увеличить цену в два раза для всех товаров, которые не закончились и на складе их есть еще как минимум 25 единиц.
Как вы видите мы просто совершаем манипуляции над DataTable, которую нам вернул метод GetProducts() и сохраняем изменения с помощью команды Update() которой в качестве параметра передаем нашу модифицированную DataTable(). Код, приведенный ниже показывает как можно программно изменить, добавить или удалить одиночную запись
Создание собственных методов удаление, добавления и изменения данныхМетоды рассмотренные в предыдущей части просто выполняли свою работу, но иногда надо что-то вернуть, самый распространенный пример - это когда при добавлении новой записи нужно получить тдентификатор этой записи, его можно получить с помощью функции SQL SCOPE_IDENTITY(). Этим мы сейчас и займемся. Откроем мастер создания нового запроса, если забыли как это делать - необходимо кликнуть правой кнопкой мыши по ProductsTableAdapter и выбрать Add/Query В первом шаге мастера необходимо выбрать тип запроса INSERT: На следующем шаге вы увидите уже сформированный текст запроса, но нам необходимо его модифицировать добавив строку SELECT SCOPE_IDENTITY() в конец запроса: И, наконец, ввести название запроса Но это еще не все. По умолчанию все запросы, выполняющие наши насущные операции добавления, изменения или удаления данных принадлежат к разряду non-query, в свойствах запроса нам необходимо изменить свойство ExecuteMode на Scalar Пример использования метода на деле:
Шаг 5. Приведение DAL к финальному видуНа данном этапе мы уже имеем TableAdapter и несколько методов, но этого же мало! Да и не устраивает нас то, что в поле CategoryID выводится идентификатор, нам хочется, чтобы выводилось еще и название категории. Для этого модифицируем наш SELECT запрос ProductsTableAdapter следующим образом:
После внесения этих коррективов наша таблица будет содержать два дополнительных поля: CategoryName и SupplierName Теперь вы можете переопределить и второй метод таким же образом. Так же вы можете поменять запросы удаления, вставки, обновления. Добавление оставшихся TableAdaptersВы уже умеете добавлять TableAdapters и создавать запросы, поэтому добавьте оставшиеся TableAdapter самостоятельно, я приведу лишь текст запросов на выборку. В финале у вас должно получиться что-то вроде: · ProductsTableAdapter o GetProducts: o GetProductsByCategoryID: o GetProductsBySupplierID: o GetProductByProductID: · CategoriesTableAdapter o GetCategories: o GetCategoryByCategoryID: · SuppliersTableAdapter o GetSuppliers: o GetSuppliersByCountry: o GetSupplierBySupplierID: · EmployeesTableAdapter o GetEmployees: o GetEmployeesByManager: o GetEmployeeByEmployeeID: И выглядеть все это будет примерно следующим образом: Добавление произвольного кода в DALВы можете посмотреть исходный код вшего Typed DataSet нажав на нем правой кнопкой мыши и выбрав пункт "View Code" Вы также можете просмотреть исходные коды методов, для этого откройте Class View (View/Class View) и на нужном методе щелкните правой кнопкой мыши, и выберите Go To Definition
Так же вы можете создать partial класс и добавить свои методы и свойства в нужный класс, например:
Таким образом мы определили метод, который для каждого Supplier находит список товаров с его SupplierID. Так же вы можете увидеть, что написанный метод появился в Class View: А теперь мы сделаем вот что: создадим GridView, в котором будет выводится список Suppliers. В нем будет 2 столбца: CompanyName (Supplier) и список товаров этого Supplier (Products) Создадим файл SuppliersAndProducts.aspx SuppliersAndProducts.aspx <%@ Page Language="C#" CodeFile="SuppliersAndProducts.aspx.cs" AutoEventWireup="true" Inherits="SuppliersAndProducts" %> В оригинале статьи автор приводит другую строку, но у меня в VS 2008 она не заработала, поэтому я её заменил. В оригинале строка DataSource выглядит так:
SuppliersAndProducts.aspx.cs using System; В итоге мы получим вот такой привлекательный результат: ЗаключениеСоздание DAL - одно из важнейших этапов разработки. Пожалуй, оно даолжно быть первым этам разработки приложения. С помощью VS вы можете создать DAL, основанный на Typed DataSets за 10-15 минут, без написания какого-либо кода. В следующем уроке мы будем основываться на созданном DAL, мы введес несколько бизнес правил и увидим, как можно вынести в отдельный уровень бизнес логику. Удачного программирования! ПослесловиеЯ не претендую на роль замечательного переводчика, рассказчика или автора статей, в данной статье я пытался просто описать то, что понял из статьи Скотта Митчелла. За орфографию и стилистику сильно прошу не карать, т.к. писал статью более четырех часов, сейчас у меня на часах 2:34 ночи. Скоро, надеюсь, напишу следующую, а пока - будьте умнее, изучайте ASP.NET и пишите по настоящему крупные web-приложения! |