ADO.NET DataSet 데이터 원본과 관계없이 일관된 관계형 프로그래밍 모델을 제공하는 데이터의 메모리 상주 표현입니다. 테이블 DataSet
, 제약 조건 및 테이블 간의 관계를 포함하는 전체 데이터 집합을 나타냅니다.
DataSet
데이터 원본 DataSet
과 독립적이므로 애플리케이션에 대한 로컬 데이터와 여러 데이터 원본의 데이터를 포함할 수 있습니다. 기존 데이터 원본과의 상호 작용은 .를 DataAdapter
통해 제어됩니다.
SelectCommand
의 DataAdapter
속성은 데이터 원본에서 데이터를 검색하는 Command
객체입니다.
InsertCommand
, UpdateCommand
, 및 DeleteCommand
속성은 DataAdapter
의 데이터를 수정한 내용에 따라 데이터 원본의 데이터를 업데이트하고 관리하는 Command
개체입니다. 이러한 속성은 DataAdapters를 사용하여 데이터 원본을 업데이트하는 데 자세히 설명되어 있습니다.
Fill
의 DataAdapter
메서드는 DataSet
의 SelectCommand
결과를 DataAdapter
에 채우는 데 사용됩니다.
Fill
는 채워질 DataSet
와 DataTable
객체 또는 DataTable
에서 반환된 행으로 채울 SelectCommand
의 이름을 인수로 받습니다.
비고
DataAdapter
를 사용하여 테이블의 모든 행을 검색하는 것은 시간이 걸립니다. 특히 테이블에 많은 행이 있는 경우 더욱 그렇습니다. 이는 데이터베이스에 액세스하고, 데이터를 찾아서 처리한 다음, 클라이언트로 데이터를 전송하는 데 시간이 오래 걸리기 때문입니다. 모든 테이블을 클라이언트로 끌어와서 서버의 모든 행도 잠깁니다. 성능을 향상시키기 위해 절을 WHERE
사용하여 클라이언트에 반환되는 행 수를 크게 줄일 수 있습니다. 문에 필요한 열만 명시적으로 나열하여 클라이언트에 반환되는 데이터의 양을 줄일 수도 있습니다 SELECT
. 또 다른 좋은 해결 방법은 일괄 처리로 행을 검색하고(예: 한 번에 수백 개의 행) 클라이언트가 현재 일괄 처리로 완료된 경우에만 다음 일괄 처리를 검색하는 것입니다.
이 메서드는 Fill
개체를 DataReader
암시적으로 사용하여 테이블을 DataSet
만드는 데 사용되는 열 이름 및 형식을 반환하고 데이터를 사용하여 테이블 DataSet
의 행을 채웁니다. 테이블 및 열은 아직 없는 경우에만 만들어집니다. 그렇지 않으면 Fill
기존 스키마를 DataSet
사용합니다. 열 형식은 ADO.NET 데이터 형식 매핑의 테이블에 따라 .NET Framework 형식으로 만들어집니다. 기본 키는 데이터 원본 DataAdapter
에 있고 .MissingSchemaAction
MissingSchemaAction
설정 AddWithKey
되지 않는 한 만들어지지 않습니다. 테이블에 대한 기본 키가 있는 경우 Fill
기본 키 열 값이 데이터 DataSet
원본에서 반환된 행의 값과 일치하는 행에 대한 데이터 원본의 데이터로 데이터를 덮어씁니다. 기본 키를 찾을 수 없으면, 데이터가 DataSet
의 테이블에 추가됩니다.
Fill
는 DataSet
를 채울 때 모든 존재할 수 있는 매핑을 사용합니다 (DataAdapter DataTable 및 DataColumn 매핑 참조).
비고
SelectCommand
가 OUTER JOIN 결과를 반환하는 경우, DataAdapter
는 생성된 PrimaryKey
에 대해 DataTable
값을 설정하지 않습니다. 중복 행이 올바르게 해결되도록 PrimaryKey
을 직접 정의해야 합니다. 자세한 내용은 기본 키 정의합니다.
다음 코드 예제는 Microsoft SQL Server SqlDataAdapter 데이터베이스에 대한 SqlConnection를 사용하여 Northwind
의 인스턴스를 생성하고, DataTable에 고객 목록을 DataSet
로 채웁니다.
SqlConnection 생성자에 전달된 SQL 문과 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
가 완료되었을 때 연결이 닫힙니다. 이것은 Fill
또는 Update
와 같은 단일 작업을 처리할 때 코드를 간소화할 수 있습니다. 그러나 열린 연결이 필요한 여러 작업을 수행하는 경우 명시적으로 메서드Open
를 호출하고 Connection
데이터 원본에 대해 작업을 수행한 다음 메서드를 호출 Close
하여 애플리케이션의 Connection
성능을 향상시킬 수 있습니다. 다른 클라이언트 애플리케이션에서 사용할 리소스를 해제하려면 데이터 원본에 대한 연결을 가능한 한 짧게 열어 두어야 합니다.
여러 결과 집합
DataAdapter
가 여러 결과 집합을 만나면, DataSet
에 여러 테이블이 생성됩니다. 테이블에는 Table0부터 "Table"이라는 증분 기본 이름이 지정됩니다. TableN으로 계속됩니다. 테이블 이름이 메서드에 Fill
인수로 전달되면 TableName0의 "TableName"부터 테이블 이름N의 증분 기본 이름이 테이블에 지정됩니다.
여러 DataAdapters에서 데이터셋 채우기
어떤 수의 DataAdapter
개체를 DataSet
와 함께 사용할 수 있습니다. 각각의 DataAdapter
는 하나 이상의 DataTable
객체를 채우고 관련 데이터 소스로의 업데이트를 처리할 수 있습니다.
DataRelation
및 Constraint
개체를 로컬에 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
에는 두 개의 테이블인 Customers
와 CustomersOrders
가 포함되며, 여기서 CustomersOrders
는 장 열을 나타냅니다.
Orders
라는 추가 열이 Customers
테이블에 추가되고 CustomersOrders
라는 추가 열이 CustomersOrders
테이블에 추가됩니다.
Orders
테이블의 Customers
열이 자동 증가로 설정됩니다. 테이블에 추가된 열을 사용하여 DataRelation
을(를) 만들고, CustomersOrders
는 Customers
을(를) 부모 테이블로 합니다. 다음 표에서는 몇 가지 샘플 결과를 보여 줍니다.
TableName: 고객
고객ID | 회사 이름 | 주문 |
---|---|---|
ALFKI | 알프레드 푸터키스트 | 0 |
ANATR | Ana Trujillo 샌드위치와 아이스크림 | 1 |
테이블 이름: 고객 주문
고객ID | 주문 ID | 고객 주문 |
---|---|---|
ALFKI | 10643 | 0 |
ALFKI | 10692 | 0 |
ANATR | 10308 | 1 |
ANATR | 10625 | 1 |