Поделиться через


Заполнение набора данных из DataAdapter

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, а также список заказов из NorthwindNorthwind базы данных, хранящейся в 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

См. также