"Сведения, которыми не располагали древние, были очень обширны."
Марк Твен
Для того чтобы создавать интересные web-страницы, необходимо наполнить их динамичным, обновляемым содержанием. Особенно необходимо это в бизнес-приложениях — банковских, интернет-магазинах и аукционах. Важная часть работы, которую выполняет разработчик ASP .NET — это связывание своих страниц с источниками данных, отображение данных на странице, создание удобных средств взаимодействия с ними.
Для хранения данных чаще всего используются
Данные в
Представления (View) создаются на основе одной или нескольких
Для наглядности рассмотрим эти понятия на примере. В свое время я работала с базой данных кадров одного предприятия. Как создать такую базу? Прежде всего нам нужна
| ID | Имя | Фамилия | Отчество | Дата рождения | Дата приема | Должность |
|---|---|---|---|---|---|---|
| 1 | Петр | Васечкин | Иванович | 1965 | 2001 | Завхоз |
| 2 | Василий | Петров | Сидорович | 1977 | 2003 | Программист |
и т.д.
Отделу кадров нужна информация о перемещениях сотрудников. Для этого заведена отдельная
| Должности | ||
|---|---|---|
| ID | Название должности | Минимальный оклад |
| 1 | Директор | 1 |
| 2 | Завхоз | 10 |
| 3 | Программист | 20 |
| 4 | Уборщица | 100 |
Числа в левой колонке — это
| Перемещения | ||||
|---|---|---|---|---|
| ID | Сотрудник | Должность | Назначение | Дата |
| 1235 | 123 | 10 | 11 | 20.06.06 |
Этот процесс называется нормализацией. Чтобы для отчета восстановить информацию о перемещении, в запросе нужно связать данные из разных
В результате этого запроса будет создано
SELECT Employees.LastName, Employees.FirstName, Titles.Title, Titles_1.Title, Promotions.PromotionDate FROM Titles AS Titles_1 INNER JOIN ((Promotions INNER JOIN Titles ON Promotions.TitleBefore = Titles.id) INNER JOIN Employees ON Promotions.EmployeeID = Employees.EmployeeID) ON Titles_1.id = Promotions.TitleAfter;
Множество
Подробнее о теории баз данных можно прочитать в других курсах. Перейдем к конкретным примерам связывания с базами данных на web-страницах.
У каждого пользователя Windows наверняка имеется программа Access. Это однопользовательская
Для работы с базами данных используется язык структурированных запросов —
Для обращения к базам данных из внешних программ существуют специальные механизмы. В Windows это ODBC — открытый интерфейс взаимодействия с базами данных. Он позволяет приложениям, работающим под Windows или другими ОС, общаться с различными серверами реляционных баз данных.
Для конфигурирования источников данных на вашем компьютере зайдите в Control Panel, Administrative Tools, Data Sources (ODBC).
Мы видим, что ODBC при наличии нужного драйвера позволяет связываться с различными базами данных — Access, FoxPro, Oracle, Microsoft
Веб-проект в Visual Studio 2005 содержит предопределенную папку App_Data. В ней могут храниться файлы с данными, которые используются в приложении. Это могут быть файлы .mdf (MS
Соединение в ADO.NET может происходить с помощью различных провайдеров. В настоящее время рекомендуется работать с помощью провайдера MS
Классы
System.Data — это ядро
System.Data.Common — базовые классы для всех провайдеров данных — DbConnection, DbCommand, DbDataAdapter.
В System.Data.OleDb находятся классы, позволяющие работать с источниками данных OleDb, в том числе с MS OleDbConnection, OleDbDataAdapter и OleDbCommand.
System.Data.Odbc содержит классы, которые работают с источниками данных ODBC посредством провайдера .NET ODBC. Классы имеют аналогичные имена с префиксом Odbc.
System.Data.SqlClient. Здесь определен провайдер данных для , SqlTransaction, SqlCommand и другие.
В System.Data.SqlTypes находятся классы, представляющие типы данных
Классы Disconnected определяют базовую структуру данных, например, DataTable. Они независимы от каких-либо провайдеров данных и могут создаваться и заселяться данными непосредственно в программе. Классы Shared — базовые и общие для всех провайдеров. Классы Data Provider — специфические для разных провайдеров.
Все провайдеры данных содержат классы соединений, адаптеров, команд. Схема типичной программы в
1. Вначале создается соединение с базой данных — класс
2. Создается объект
3. Если команда не возвращает данных, она просто выполняется с помощью одного из методов Execute. Например, это может быть удаление или обновление данных
4. Если команда возвращает выборку данных, их необходимо куда-то поместить. Решите, нужно ли вам получить данные для последующего использования без связи с базой данных или же нужно просто быстро выполнить команду. В первом случае нужно создать класс DataAdapter и с его помощью сохранить данные в DataTable. Во втором случае создается класс DataReader, который требует сохранять соединение на все время работы, хранит выборку только для чтения и позволяет двигаться только вперед. Зато чтение с помощью DataReader выполняется в несколько раз быстрее, чем в DataAdapter.
5. Задать полученный DataReader как источник данных элемента управления или вывести их на страницу другим способом.
Объект OleDbConnection, , OdbcConnection — наследники класса
| Свойство | Описание |
|---|---|
| DataSource | Путь к базе данных в файловой системе при использовании Oledb, имя экземпляра базы сервера при использовании |
| Database | Возвращает имя базы данных, используемой в объекте |
| State | Возвращает текущее |
| ConnectionString |
Все свойства, кроме ConnectionString, — только для чтения.
Объект SELECT, то данные обычно помещаются в DataReader. Методы и свойства определены в абстрактном классе DbCommand (через интерфейс IDbCommand ), и их реализуют частные ненаследуемые классы OleDbCommand, SqlCommand, OdbcCommand.
Свойство CommandType может принимать значения из перечисления CommandType. По умолчанию это Text, то есть выполняется непосредственно текст команды TableDirect означает, что в результате выполнения команды будет возвращено все содержание
Свойство CommandText хранит текст запроса
CommandTimeout задает время ожидания ответа, по умолчанию равное 30 секундам. Если команда не выполнится в течение этого времени, будет выброшено исключение.
Процедуры сервера нуждаются в параметрах. Они хранятся в коллекции Parameters и имеют тип SqlParameter. Текстовые команды также могут получать параметры, перед которыми ставится префикс @. Например:
" SELECT * FROM CUSTOMERS WHERE CITY = @CITY AND CONTACTNAME = @CONTACT "
Часто используется метод ExecuteNonQuery. С помощью него можно выполнить любую операцию с базами данных, которая не связана с запросом и получением данных, например, обновление, удаление Select, Update, Delete.
ExecuteScalar возвращает результат запроса в случае, если это одно-единственное значение. Например, нужно узнать количество заказов конкретного покупателя. Запрос выполняется с помощью команды "Select count * where customerid=1". Ее результат — выборка из одной строки и одного столбца. Ее можно выполнить и с помощью метода ExecuteReader, но ExecuteScalar будет выполняться быстрее. Если запрос возвратит большее количество строк или столбцов, они будут проигнорированы.
ExecuteRow возвращает единственную
ExecuteReader выполняется, если нужно получить табличные данные. Результат выполнения — курсор, в котором можно двигаться только от начала до конца.
В результате выполнения метода ExecuteReader объекта DataReader. Всегда закрывайте соединения после использования, иначе оно останется активным и будет занимать ресурсы. Это можно сделать двумя способами. Первый — вызвать ExecuteReader, который принимает параметр типа CommandBehavior со значением CommandBehavior.CloseConnection. В таком случае необходимо перелистать полученную выборку от начала до конца, и соединение закроется, когда будет достигнут конец. Если вы не хотите прочитать все данные, можете самостоятельно закрыть соединение методом Close:
public void CreateMySqlDataReader(string mySelectQuery, string
myConnectionString)
{
SqlConnection myConnection = new
SqlConnection(myConnectionString);
SqlCommand myCommand = new SqlCommand(mySelectQuery,
myConnection);
myCommand.CommandType = CommandType.Text;
myCommand.Connection.Open();
SqlDataReader myReader =
myCommand.ExecuteReader(CommandBehavior.CloseConnection);
while (myReader.Read())
{
Response.Write(myReader.GetString(0) + "<br>");
}
myReader.Close();
myConnection.Close();
}
Развитые
Для поддержки SqlTransaction и ему подобные. У объекта Transaction. Метод BeginTransaction объекта Connection заставляет базу данных перейти в режим
Кроме того, необходимо всегда заключать программный код, работающий с базами данных, в блоки try/catch, так как работа часто идет с удаленными серверами и могут происходить самые разные ошибки как в сети, так и при работе самого сервера.
При этом выбрасывается исключение SqlException или OleDbException:
public void RunTransaction(string[] Queries, string
myConnectionString)
{
SqlConnection conn = null;
SqlTransaction trans = null;
try
{
conn = new SqlConnection(myConnectionString);
conn.Open();
trans = conn.BeginTransaction();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.Transaction = trans;
foreach (string Query in Queries)
{
cmd.CommandText = Query;
cmd.ExecuteNonQuery();
}
trans.Commit();
}
catch (SqlException SqlEx)
{
if (trans != null)
{
trans.Rollback();
}
throw new Exception("An error occurred while transaction",
SqlEx);
return;
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
DbDataAdapter является родительским классом для SqlDataAdapter, OleDbDataAdapter, OdbcDataAdapter. Этот класс содержит 4 объекта типа DataAdapter обеспечивают
SelectCommand — эта команда используется для выборки данных из базы. При этом класс DataTable заполняется данными.
UpdateCommand — обновляет данные (редактирование
InsertCommand — добавление новых
DeleteCommand — команда для удаления
Метод Fill класса DbDataAdapter заполняет объекты DataTable данными, прочитанными в результате выполнения команды SelectCommand. Эта команда должна быть запросом Select. Если Fill перегружен 8 раз. Например, DbDataAdapter.Fill Method ( String ) добавляет в
DataTable tblProducts = data.Tables["Products"];
Метод DbDataAdapter.Update записывает в базу данных все изменения, которые произошли в связанном с ним объекте
DataTable и связи между ними. Класс
Коллекция Tables, а отношений — в свойстве Relations.
Основываясь на DataView.
Напишем страницу, в которой будут использоваться представленные классы.
База Northwind входит в комплект SDK. Ее можно установить на сервере, запустив командную строку SQLExpress:
sqlcmd -E -S (local)\SQLExpress -i InstNwnd.sql
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Работа с базой</title>
</head>
<body>
<form id="Form1" runat="server">
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
<asp:DataGrid id="DataGrid1" runat="server"></asp:DataGrid>
</form>
</body>
</html>
Файл с кодом:
using System;
using System.Data;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
String strConnect;
String strCommand;
strConnect = @"Data Source=.\SQLExpress;Initial
Catalog=Northwind;Integrated Security=True";
SqlConnection myConn = new SqlConnection(strConnect);
strCommand = "SELECT CategoryName, CategoryID FROM
Categories";
SqlDataAdapter myData = new SqlDataAdapter(strCommand,
myConn);
DataSet DataSet1 = new DataSet();
myData.Fill(DataSet1, "Categories");
strCommand = "SELECT ProductName, UnitPrice, CategoryID
FROM Products";
myData.SelectCommand.CommandText = strCommand;
myData.Fill(DataSet1, "Products");
DataSet1.Relations.Add(DataSet1.Tables[0].Columns["CategoryID"],
DataSet1.Tables[1].Columns["CategoryID"]);
DataView myView = new DataView(DataSet1.Tables["Products"],
"", "ProductName", DataViewRowState.CurrentRows);
DataGrid1.DataSource = myView;
DataGrid1.DataBind();
DropDownList1.DataSource = DataSet1.Tables[0];
DropDownList1.DataTextField = "CategoryName";
DropDownList1.DataValueField = "CategoryID";
DropDownList1.DataBind();
myConn.Close();
}
}
В Visual Studio 2005 существует 3 вкладки просмотра проектов: Solution Explorer, Class Explorer,
—>
(рис 6.1) Соединение можно установить как с MS
(рис 6.2) Когда соединение создано, вы через пользовательский интерфейс можете добавлять
В лекции 3 мы создали страницы с голосованиями, но никак не обрабатывали результаты. Сейчас мы будем сохранять результаты голосования.
1. Вначале надо создать базу данных. В окне
(рис 6.3) .\SQLExpress равносильно (local) SQLExpress и означает сервер на локальной машине. Можно подключиться к серверу и по сети. Мы создали базу данных
2. Создание
| Column Name | Data Type | Allow Nulls |
| Id | int | |
| variant | nvarchar(100) | + |
| voices | int |
Создание той же самой
protected void Page_Load(object sender, EventArgs e)
{
String strCreateTable = "create table poll(id int
NOT NULL PRIMARY KEY, variant nvarchar(100), voices int DEFAULT 0)";
CreateSqlTable(strCreateTable, "Data Source=.\\SQLEXPRESS;Initial
Catalog=Polls;Integrated Security=True");
}
public void CreateSqlTable(string SqlQuery, string myConnectionString)
{
SqlConnection myConnection = new SqlConnection(myConnectionString);
SqlCommand myCommand = new SqlCommand(SqlQuery, myConnection);
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
3. Заполнение
(рис 6.4) 4. Создание серверной процедуры. При каждом голосовании значение
CREATE PROCEDURE dbo.CountVote ( @choiceid int = 0 ) AS DECLARE @Count INT SELECT @Count = voices FROM poll WHERE id=@choiceid UPDATE poll SET voices=@Count+1 WHERE id=@choiceid RETURN
В этой процедуре заключены 2 взаимосвязанных команды, связанных общей логикой, а для выполнения ее понадобится только один объект
Оператор SELECT извлекает WHERE. Так как id — @Count.
5. Привязка к данным. На новой странице создайте элементы Button и RadioButtonList (можно и CheckBoxList ) перетаскиванием из Toolbox. На RadioButtonList имеется стрелка, открывающая . С помощью него можно сконфигурировать соединение с нужной DataValueField списка переключателей
и будет передаваться в процедуру сервера как параметр.
(рис 6.5) При желании на этом шаге можно отсортировать значения, например, по алфавитному порядку текстов нажатием на кнопку ORDER BY. На предпоследнем шаге можно протестировать полученный запрос, и если все в порядке, то на последнем шаге ставим variant как источник для показа и id для значений. На странице должно получиться примерно следующее:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Voting.aspx.cs" Inherits="Voting" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Голосование для программистов</title>
</head>
<body>
<br /><br />
Какой язык программирования Вы предпочитаете?<br />
<form runat="server" id="voting">
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
DataSourceID="SqlDataSource1" DataTextField="variant"
DataValueField="id">
</asp:RadioButtonList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:PollsConnectionString %>"
SelectCommand="SELECT [id], [variant] FROM [poll] ORDER
BY [variant] "></asp:SqlDataSource>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" /><br />
<br />
<br /><br />
</form>
<asp:Label id="Message" runat="server" />
</body>
</html>
6. Обработка результатов. Процедуру необходимо вызвать с параметром, взятым из свойства Value группы переключателей. Свойство Parameters SqlCommand является коллекцией, в данном случае в нее надо добавить один элемент:
public partial class Voting : System.Web.UI.Page
{
public void ExecuteStoredProcedure(string ProcedureName,
string myConnectionString, int id)
{
SqlConnection myConnection = new
SqlConnection(myConnectionString);
SqlCommand myCommand = new SqlCommand(ProcedureName,
myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
SqlParameter myParm = myCommand.Parameters.Add("@choiceid",
SqlDbType.Int, 4);
myParm.Value = id;
myCommand.Connection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
protected void Page_Load(object sender, EventArgs e)
{
String strConnection = "Data Source=.\\SQLEXPRESS;Initial
Catalog=Polls;Integrated Security=True";
if (Page.IsPostBack)
{
String strProc="CountVote";
Message.Text = RadioButtonList1.SelectedValue;
ExecuteStoredProcedure(strProc, strConnection,
Int32.Parse(RadioButtonList1.SelectedValue) );
}
}
}
При работе с базами данных важно соблюдать принцип: "занимай ресурсы как можно позже и освобождай как можно раньше". Поэтому соединение закрывается сразу после выполнения процедуры сервера.
Работа с базами данных в ASP .NET — настолько обширная тема, что ее невозможно охватить в одной лекции. Хотя классы
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.