Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
ADO.NET DataSet — это резидентное представление данных, которое обеспечивает согласованную реляционную модель программирования независимо от источника данных.
DataSet
представляет полный набор данных, включающий таблицы, ограничения и связи между таблицами. Поскольку DataSet
является независимым от источника данных, DataSet
может включать локальные данные приложения и данные из нескольких источников данных. Взаимодействие с существующими источниками данных управляется с помощью DataAdapter
.
Свойство SelectCommand
объекта DataAdapter
— это объект Command
, который извлекает данные из источника данных. Свойства InsertCommand
, UpdateCommand
, и DeleteCommand
объекта DataAdapter
— это объекты Command
, которые управляют обновлениями данных в источнике данных в соответствии с изменениями, внесенными в данные в объекте DataSet
. Эти свойства подробно описаны в обновлении источников данных с помощью DataAdapters.
Метод Fill
используется для заполнения DataAdapter
результатами DataSet
объекта SelectCommand
из DataAdapter
.
Fill
принимает в качестве аргументов DataSet
, который должен быть заполнен, и DataTable
объект или имя DataTable
, который будет заполнен строками, возвращаемыми из SelectCommand
.
Замечание
Использование DataAdapter
для извлечения всей таблицы занимает время, особенно если в таблице много строк. Это связано с тем, что доступ к базе данных, поиск и обработка данных, а затем передача данных клиенту занимает много времени. Перенос всей таблицы на клиент также блокирует все строки на сервере. Чтобы повысить производительность, можно использовать WHERE
предложение, чтобы значительно уменьшить количество строк, возвращаемых клиенту. Вы также можете уменьшить объем данных, возвращаемых клиенту, только явно перечисляя обязательные столбцы в инструкции SELECT
. Еще одним хорошим решением является получение строк в пакетах (например, несколько сотен строк за раз) и получение следующего пакета только после завершения работы клиента с текущим пакетом.
Метод Fill
неявно использует объект DataReader
, чтобы вернуть имена столбцов и типы, используемые для создания таблиц в DataSet
, и данные для заполнения строк таблиц в DataSet
. Таблицы и столбцы создаются только в том случае, если они еще не существуют; в противном случае Fill
использует существующую DataSet
схему. Типы столбцов создаются как типы .NET Framework в соответствии с таблицами в сопоставлениях типов данных в ADO.NET. Первичные ключи не создаются, если они не существуют в источнике данных, и DataAdapter
.MissingSchemaAction
задано значение MissingSchemaAction
.AddWithKey
. Если Fill
обнаруживается, что первичный ключ существует для таблицы, он перезаписывает данные из DataSet
источника данных для строк, где значения столбцов первичного ключа соответствуют значениям строки, возвращаемой из источника данных. Если первичный ключ не найден, данные добавляются в таблицы в DataSet
.
Fill
использует любые сопоставления, которые могут существовать при заполнении DataSet
(см. статью DataAdapter DataTable и DataColumn Mappings).
Замечание
Если SelectCommand
возвращает результаты ВНЕШНЕГО СОЕДИНЕНИЯ, DataAdapter
не устанавливает значение PrimaryKey
для результирующего DataTable
. Вы должны самостоятельно определить PrimaryKey
, чтобы убедиться, что дублирующиеся строки разрешаются правильно. Дополнительные сведения см. в разделе "Определение первичных ключей".
В следующем примере кода создается экземпляр SqlDataAdapter, подключающийся к базе данных Microsoft SQL Server SqlConnection с помощью Northwind
и заполняющий DataTable в DataSet
списком клиентов. SQL инструкции и SqlConnection аргументы, передаваемые конструктору SqlDataAdapter, используются для создания свойства SelectCommand объекта SqlDataAdapter.
Пример
' Assumes that connection is a valid SqlConnection object.
Dim queryString As String = _
"SELECT CustomerID, CompanyName FROM dbo.Customers"
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
queryString, connection)
Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")
// Assumes that connection is a valid SqlConnection object.
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
Замечание
Код, показанный в этом примере, не открывает и закрывает Connection
явно. Метод Fill
автоматически открывает Connection
, который используется DataAdapter
, если обнаружит, что подключение еще не открыто. Если Fill
открыл подключение, оно также закроет подключение, когда Fill
завершится. Это может упростить код при работе с одной операцией, такой как a Fill
или an Update
. Однако при выполнении нескольких операций, требующих открытого подключения, можно повысить производительность приложения, явно вызвав метод Open
объекта Connection
, выполняя операции с источником данных, а затем вызывая метод Close
объекта Connection
. Необходимо попытаться сохранить подключения к источнику данных открытым как можно кратко, чтобы освободить ресурсы для использования другими клиентскими приложениями.
Несколько результирующих наборов
При обнаружении DataAdapter
нескольких результирующих наборов создается несколько таблиц в DataSet
. Таблицам присваивается добавочное имя по умолчанию таблицыN, начиная с "Table" для Table0. Если имя таблицы передается в качестве аргумента Fill
методу, таблицы получают добавочное имя по умолчанию TableNameN, начиная с tableName для TableName0.
Заполнение DataSet из нескольких адаптеров данных
Любое количество DataAdapter
объектов можно использовать с DataSet
.
DataAdapter
можно использовать для заполнения одного или нескольких объектов DataTable
и отражения изменений обратно в соответствующий источник данных.
DataRelation
и Constraint
объекты можно добавить локально в DataSet
, что позволяет связывать данные из несходных источников данных. Например, DataSet
может содержать данные из базы данных Microsoft SQL Server, базы данных IBM DB2, предоставляемой с помощью OLE DB, и источника данных, который передает XML. Один или несколько DataAdapter
объектов могут обрабатывать обмен данными с каждым источником данных.
Пример
В следующем примере кода заполняется список клиентов из базы данных в Microsoft SQL Server, а также список заказов из Northwind
Northwind
базы данных, хранящейся в Microsoft Access 2000. Заполненные таблицы связаны с DataRelation
, а затем отображается список клиентов вместе с заказами для этого клиента. Дополнительные сведения об DataRelation
объектах см. в разделе «Добавление DataRelations» и «Навигация по DataRelations».
' Assumes that customerConnection is a valid SqlConnection object.
' Assumes that orderConnection is a valid OleDbConnection object.
Dim custAdapter As SqlDataAdapter = New SqlDataAdapter( _
"SELECT * FROM dbo.Customers", customerConnection)
Dim ordAdapter As OleDbDataAdapter = New OleDbDataAdapter( _
"SELECT * FROM Orders", orderConnection)
Dim customerOrders As DataSet = New DataSet()
custAdapter.Fill(customerOrders, "Customers")
ordAdapter.Fill(customerOrders, "Orders")
Dim relation As DataRelation = _
customerOrders.Relations.Add("CustOrders", _
customerOrders.Tables("Customers").Columns("CustomerID"), _
customerOrders.Tables("Orders").Columns("CustomerID"))
Dim pRow, cRow As DataRow
For Each pRow In customerOrders.Tables("Customers").Rows
Console.WriteLine(pRow("CustomerID").ToString())
For Each cRow In pRow.GetChildRows(relation)
Console.WriteLine(vbTab & cRow("OrderID").ToString())
Next
Next
// Assumes that customerConnection is a valid SqlConnection object.
// Assumes that orderConnection is a valid OleDbConnection object.
SqlDataAdapter custAdapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers", customerConnection);
OleDbDataAdapter ordAdapter = new OleDbDataAdapter(
"SELECT * FROM Orders", orderConnection);
DataSet customerOrders = new DataSet();
custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");
DataRelation relation = customerOrders.Relations.Add("CustOrders",
customerOrders.Tables["Customers"].Columns["CustomerID"],
customerOrders.Tables["Orders"].Columns["CustomerID"]);
foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
{
Console.WriteLine(pRow["CustomerID"]);
foreach (DataRow cRow in pRow.GetChildRows(relation))
Console.WriteLine("\t" + cRow["OrderID"]);
}
Десятичный тип SQL Server
По умолчанию данные DataSet
хранятся с помощью типов данных .NET Framework. Для большинства приложений они обеспечивают удобное представление сведений об источнике данных. Однако это представление может вызвать проблему, если тип данных в источнике данных является десятичным или числовым типом данных SQL Server. Тип данных .NET Framework decimal
позволяет не более 28 значимых цифр, а тип данных SQL Server decimal
— 38 значимых цифр. Если SqlDataAdapter
определяет во время Fill
операции, что точность поля SQL Server decimal
превышает 28 символов, текущая строка не добавляется в DataTable
. Событие FillError
вместо этого позволяет определить, произойдет ли потеря точности, и соответствующе отреагировать. Дополнительные сведения о событии FillError
см. в разделе "Обработка событий DataAdapter". Чтобы получить значение SQL Server decimal
, можно также использовать SqlDataReader объект и вызвать GetSqlDecimal метод.
ADO.NET 2.0 ввел расширенную поддержку System.Data.SqlTypes в DataSet
. Дополнительные сведения см. в разделе SqlTypes и DataSet.
Главы OLE DB
Иерархические наборы строк, или главы (тип OLE DB DBTYPE_HCHAPTER
, тип ADO adChapter
) можно использовать для заполнения содержимого DataSet
.
OleDbDataAdapter При обнаружении главного столбца во время операции Fill
создается таблица для главного столбца, и эта таблица заполняется столбцами и строками из главы. Таблица, созданная для разделенного на главы столбца, называется с использованием имени родительской таблицы и имени столбца с главами в формате ParentTableNameChapteredColumnName. Если таблица с именем, соответствующим заглавному столбцу, уже существует в DataSet
, текущая таблица заполняется данными из главы. Если в существующей таблице нет столбца, который соответствует столбцу, найденном в главе, добавляется новый столбец.
Перед тем как таблицы в DataSet
будут заполнены данными из столбцов, разделённых на главы, создается связь между родительскими и дочерними таблицами иерархического набора строк, добавляя целочисленный столбец в обе таблицы, устанавливая автоматическое увеличение для родительского столбца и создавая DataRelation
с использованием добавленных столбцов из обеих таблиц. Добавленная реляционная связь называется с помощью родительской таблицы и имен столбцов глав в форме ParentTableNameChapterColumnName.
Обратите внимание, что связанный столбец существует только в объекте DataSet
. Последующие заполнения из источника данных могут привести к добавлению новых строк в таблицы вместо объединения изменений в существующие строки.
Обратите внимание, что при использовании перегрузки DataAdapter.Fill
, которая принимает значение DataTable
, заполняется только эта таблица. Столбец целого числа с автоматическим увеличением будет добавлен в таблицу, но дочерняя таблица не будет создана или заполнена, и отношение не будет создано.
В следующем примере поставщик MSDataShape используется для создания столбца заказов для каждого клиента в списке клиентов. Затем DataSet
заполняется данными.
Using connection As OleDbConnection = New OleDbConnection( _
"Provider=MSDataShape;Data Provider=SQLOLEDB;" & _
"Data Source=(local);Integrated " & _
"Security=SSPI;Initial Catalog=northwind")
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter( _
"SHAPE {SELECT CustomerID, CompanyName FROM Customers} " & _
"APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " & _
"RELATE CustomerID TO CustomerID)", connection)
Dim customers As DataSet = New DataSet()
adapter.Fill(customers, "Customers")
End Using
using (OleDbConnection connection = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
"Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind"))
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
"APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +
"RELATE CustomerID TO CustomerID)", connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
}
После завершения операции Fill
, DataSet
содержит две таблицы: Customers
и CustomersOrders
, где столбец по главам представлен CustomersOrders
. В таблицу Orders
добавляется дополнительный столбец Customers
, а в таблицу CustomersOrders
добавляется дополнительный столбец CustomersOrders
. В таблице Orders
для столбца Customers
задан автоинкремент.
DataRelation
, CustomersOrders
создается с помощью столбцов, которые были добавлены в таблицы, используя Customers
в качестве родительской таблицы. В следующих таблицах показаны некоторые примеры результатов.
Название таблицы: Клиенты
Идентификатор клиента | Имя Компании | Заказы |
---|---|---|
ALFKI | Альфредс Кормушка | 0 |
ANATR | Ана Трухильо Emparedados y helados | 1 |
TableName: ЗаказыКлиентов
Идентификатор клиента | Идентификатор заказа | КлиентыЗаказы |
---|---|---|
ALFKI | 10643 | 0 |
ALFKI | 10692 | 0 |
ANATR | 10308 | 1 |
ANATR | 10625 | 1 |