다음을 통해 공유


DataAdapter에서 데이터 세트 채우기

ADO.NET DataSet 데이터 원본과 관계없이 일관된 관계형 프로그래밍 모델을 제공하는 데이터의 메모리 상주 표현입니다. 테이블 DataSet , 제약 조건 및 테이블 간의 관계를 포함하는 전체 데이터 집합을 나타냅니다. DataSet 데이터 원본 DataSet 과 독립적이므로 애플리케이션에 대한 로컬 데이터와 여러 데이터 원본의 데이터를 포함할 수 있습니다. 기존 데이터 원본과의 상호 작용은 .를 DataAdapter통해 제어됩니다.

SelectCommandDataAdapter 속성은 데이터 원본에서 데이터를 검색하는 Command 객체입니다. InsertCommand, UpdateCommand, 및 DeleteCommand 속성은 DataAdapter의 데이터를 수정한 내용에 따라 데이터 원본의 데이터를 업데이트하고 관리하는 Command 개체입니다. 이러한 속성은 DataAdapters를 사용하여 데이터 원본을 업데이트하는 데 자세히 설명되어 있습니다.

FillDataAdapter 메서드는 DataSetSelectCommand 결과를 DataAdapter에 채우는 데 사용됩니다. Fill는 채워질 DataSetDataTable 객체 또는 DataTable에서 반환된 행으로 채울 SelectCommand의 이름을 인수로 받습니다.

비고

DataAdapter를 사용하여 테이블의 모든 행을 검색하는 것은 시간이 걸립니다. 특히 테이블에 많은 행이 있는 경우 더욱 그렇습니다. 이는 데이터베이스에 액세스하고, 데이터를 찾아서 처리한 다음, 클라이언트로 데이터를 전송하는 데 시간이 오래 걸리기 때문입니다. 모든 테이블을 클라이언트로 끌어와서 서버의 모든 행도 잠깁니다. 성능을 향상시키기 위해 절을 WHERE 사용하여 클라이언트에 반환되는 행 수를 크게 줄일 수 있습니다. 문에 필요한 열만 명시적으로 나열하여 클라이언트에 반환되는 데이터의 양을 줄일 수도 있습니다 SELECT . 또 다른 좋은 해결 방법은 일괄 처리로 행을 검색하고(예: 한 번에 수백 개의 행) 클라이언트가 현재 일괄 처리로 완료된 경우에만 다음 일괄 처리를 검색하는 것입니다.

이 메서드는 Fill 개체를 DataReader 암시적으로 사용하여 테이블을 DataSet만드는 데 사용되는 열 이름 및 형식을 반환하고 데이터를 사용하여 테이블 DataSet의 행을 채웁니다. 테이블 및 열은 아직 없는 경우에만 만들어집니다. 그렇지 않으면 Fill 기존 스키마를 DataSet 사용합니다. 열 형식은 ADO.NET 데이터 형식 매핑의 테이블에 따라 .NET Framework 형식으로 만들어집니다. 기본 키는 데이터 원본 DataAdapter 에 있고 .MissingSchemaActionMissingSchemaAction 설정 AddWithKey 되지 않는 한 만들어지지 않습니다. 테이블에 대한 기본 키가 있는 경우 Fill 기본 키 열 값이 데이터 DataSet 원본에서 반환된 행의 값과 일치하는 행에 대한 데이터 원본의 데이터로 데이터를 덮어씁니다. 기본 키를 찾을 수 없으면, 데이터가 DataSet의 테이블에 추가됩니다. FillDataSet를 채울 때 모든 존재할 수 있는 매핑을 사용합니다 (DataAdapter DataTable 및 DataColumn 매핑 참조).

비고

SelectCommand가 OUTER JOIN 결과를 반환하는 경우, DataAdapter는 생성된 PrimaryKey에 대해 DataTable 값을 설정하지 않습니다. 중복 행이 올바르게 해결되도록 PrimaryKey을 직접 정의해야 합니다. 자세한 내용은 기본 키 정의합니다.

다음 코드 예제는 Microsoft SQL Server SqlDataAdapter 데이터베이스에 대한 SqlConnection를 사용하여 Northwind의 인스턴스를 생성하고, DataTable에 고객 목록을 DataSet로 채웁니다. SqlConnection 생성자에 전달된 SQL 문과 SqlDataAdapter 인수는 SelectCommandSqlDataAdapter 속성을 생성하는 데 사용됩니다.

예시

' 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 메서드는 연결이 아직 열려 있지 않은 경우 사용 중인 ConnectionDataAdapter을 암시적으로 엽니다. Fill 연결을 열면, Fill가 완료되었을 때 연결이 닫힙니다. 이것은 Fill 또는 Update와 같은 단일 작업을 처리할 때 코드를 간소화할 수 있습니다. 그러나 열린 연결이 필요한 여러 작업을 수행하는 경우 명시적으로 메서드Open를 호출하고 Connection 데이터 원본에 대해 작업을 수행한 다음 메서드를 호출 Close 하여 애플리케이션의 Connection성능을 향상시킬 수 있습니다. 다른 클라이언트 애플리케이션에서 사용할 리소스를 해제하려면 데이터 원본에 대한 연결을 가능한 한 짧게 열어 두어야 합니다.

여러 결과 집합

DataAdapter가 여러 결과 집합을 만나면, DataSet에 여러 테이블이 생성됩니다. 테이블에는 Table0부터 "Table"이라는 증분 기본 이름이 지정됩니다. TableN으로 계속됩니다. 테이블 이름이 메서드에 Fill 인수로 전달되면 TableName0의 "TableName"부터 테이블 이름N의 증분 기본 이름이 테이블에 지정됩니다.

여러 DataAdapters에서 데이터셋 채우기

어떤 수의 DataAdapter 개체를 DataSet와 함께 사용할 수 있습니다. 각각의 DataAdapter는 하나 이상의 DataTable 객체를 채우고 관련 데이터 소스로의 업데이트를 처리할 수 있습니다. DataRelationConstraint 개체를 로컬에 DataSet 추가할 수 있으므로 서로 다른 데이터 원본의 데이터를 연결할 수 있습니다. 예를 들어 Microsoft SQL Server 데이터베이스의 DataSet 데이터, OLE DB를 통해 노출된 IBM DB2 데이터베이스 및 XML을 스트리밍하는 데이터 원본을 포함할 수 있습니다. 하나 이상의 DataAdapter 개체가 각 데이터 원본에 대한 통신을 처리할 수 있습니다.

예시

다음 코드 예제에서는 Microsoft SQL Server의 데이터베이스에서 Northwind 고객 목록과 Microsoft Access 2000에 저장된 데이터베이스의 주문 Northwind 목록을 채웁니다. 채워진 테이블은 A DataRelation와 관련이 있으며 고객 목록은 해당 고객에 대한 주문과 함께 표시됩니다. 개체에 대한 DataRelation 자세한 내용은 DataRelations 추가DataRelation 탐색을 참조하세요.

' 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 10진수 형식

기본적으로 DataSet .NET Framework 데이터 형식을 사용하여 데이터를 저장합니다. 대부분의 애플리케이션에서 데이터 원본 정보를 편리하게 표현합니다. 그러나 데이터 원본의 데이터 형식이 SQL Server 10진수 또는 숫자 데이터 형식인 경우 이 표현으로 인해 문제가 발생할 수 있습니다. .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에 도입되었습니다. 자세한 내용은 SqlType 및 DataSet을 참조하세요.

OLE DB 챕터

계층적 행 집합 또는 장(OLE DB 형식 DBTYPE_HCHAPTER, ADO 형식 adChapter)을 사용하여 의 DataSet내용을 채울 수 있습니다. OleDbDataAdapter 작업 중에 Fill 장 열이 발견되면, 장 열을 위해 DataTable이(가) 생성되며, 그 테이블은 장의 열과 행으로 채워집니다. "ParentTableNameChapteredColumnName" 형식의 부모 테이블 이름과 장 열 이름을 모두 사용하여 장 열에 대해 만든 테이블의 이름을 지정합니다. 장 열의 이름과 일치하는 테이블이 이미 있는 DataSet 경우 현재 테이블은 장 데이터로 채워집니다. 기존 테이블에 장에서 찾은 열과 일치하는 열이 없으면 새 열이 추가됩니다.

테이블 DataSet이 장 열의 데이터로 채워지기 전에, 부모 테이블과 자식 테이블 각각에 정수 열을 추가하고, 부모 테이블의 열을 자동 증가로 설정함으로써 두 테이블에서 추가된 열을 이용하여 DataRelation을 만들어 부모 테이블과 자식 테이블 간 계층적 행 집합의 관계가 형성됩니다. 추가된 관계 이름은 "ParentTableNameChapterColumnName" 형식의 부모 테이블 및 장 열 이름을 사용하여 지정됩니다.

관련 열은 DataSet에만 존재한다는 점을 주의하세요. 데이터 원본의 후속 채우기로 인해 변경 내용이 기존 행에 병합되는 대신 새 행이 테이블에 추가될 수 있습니다.

또한 DataAdapter.Fill을(를) 받는 DataTable 오버로드를 사용하는 경우, 해당 테이블만 채워집니다. 자동 증분 정수 열은 여전히 테이블에 추가되지만 자식 테이블이 생성되거나 채워지지 않으며 관계가 만들어지지 않습니다.

다음 예제에서는 MSDataShape 공급자를 사용하여 고객 목록에서 각 고객에 대한 주문 장 열을 생성합니다. 그런 다음 A 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에는 두 개의 테이블인 CustomersCustomersOrders가 포함되며, 여기서 CustomersOrders는 장 열을 나타냅니다. Orders라는 추가 열이 Customers 테이블에 추가되고 CustomersOrders라는 추가 열이 CustomersOrders 테이블에 추가됩니다. Orders 테이블의 Customers 열이 자동 증가로 설정됩니다. 테이블에 추가된 열을 사용하여 DataRelation을(를) 만들고, CustomersOrdersCustomers을(를) 부모 테이블로 합니다. 다음 표에서는 몇 가지 샘플 결과를 보여 줍니다.

TableName: 고객

고객ID 회사 이름 주문
ALFKI 알프레드 푸터키스트 0
ANATR Ana Trujillo 샌드위치와 아이스크림 1

테이블 이름: 고객 주문

고객ID 주문 ID 고객 주문
ALFKI 10643 0
ALFKI 10692 0
ANATR 10308 1
ANATR 10625 1

참고하십시오