ADO .NET 객체 모델
ADO.NET 클래스는 크게 두 개의 컴포넌트로 나누어져 있다. 즉, 물리적인 데이터 저장소와의 커뮤니케이션을 다루는 데이터 공급자(Data Providers : 때에 따라 Managed Provider 라고도 부른다)와 실제 데이터를 나타내 주는 DataSet으로 나누어진다. 이들 두 가지 컴포넌트들은 모두 WebForm이나 WinForm과 같은 데이터 사용자(Data Consumers)와 통신을 할 수 있다.
데이터 공급자(Data Providers)
데이터 공급자 컴포넌트는 데이터 소스에 대하여 특별한 역활을 한다. .NET 프레임워크는 두개의 데이터 공급자를 포함한다. 하나는 OLE DB 데이터 소스와 통신을 하는 일반 데이터 공급자이고, 또 하나는 Microsoft SQL Server 7.0 버젼 및 그 이후 버전에 최적화 시킨 SQL Server 데이터 공급자이다. 오라클이나 DB2와 같은 기타 데이터베이스를 위한 데이터 공급자도 사용 가능할 것으로 기대된다. 또한, 개발자가 자신만의 것을 만들어 사용할 수도 있다.
.NET 프레임워크에 포함되어 있는 두 개의 데이터 공급자는 서로 동일한 객체를 포함하고 있다. 비록, 포함하고 있는 각각의 객체가 서로 다른 이름을 가지고 있고 일부 속성과 메서드가 다르지만, 이들은 동일한 객체이다. 이를 설명하기 위해서, SQL Server 공급자 객체는 SQL이라는 이름으로 시작하고(예를 들어, SqlConnection), OLE DB객체는 OleDB라는 이름으로 시작한다.(예를 들어, OleDbConnection).
Connection 객체는 데이터 소스와의 물리적인 연결을 나타낸다. Connection 객체의 속성은 데이터 공급자(OLE DB 데이터 공급자의 경우), 연결하고자 하는 데이터 소스와 데이터베이스, 그리고 연결하는 동안 사용할 문자열을 결정짓는다. Connection 객체의 메서드는 매우 간단하다. 즉, 연결을 열거나 닫고, 데이터베이스를 변경하거나 트랜잭션을 관리한다.
Command 객체는 데이터 소스에 대해 실행될 SQL 문 또는 저장 프로시저(stored procedure)를 나타낸다. Connection 객체와는 상관없이 독립적으로 Command 객체를 생성하고, 실행할 수 있다. 또한, DataSet과 데이터 소스와의 통신을 위해 DataAdapter 객체가 Command 객체를 사용한다. Command 객체는 단일 값, 한 개 또는 그 이상의 행(row) 집합, 또는 전혀 값을 리턴하지 않는 SQL 문과 저장 프로시저를 지원할 수 있다.
DataReader는 데이터 소스의 데이터 스트림을 전방향(forward-only) 및 읽기 전용으로 포함하기 위한 빠르고 오버헤드가 적은 객체이다. DataReader 객체는 코드에서 직접 생성할 수 없고, 오직 Command 객체의 ExecuteReader 메서드를 호출할 때만 생성할 수 있다.
DataAdapter는 데이터 공급자 객체들 중에서 기능적으로 가장 복합한 객체이다. DataAdapter는 Connection과 DataSet 사이의 브릿지를 제공한다. DataAdapter는 네 개의 Command 객체, 즉 SelectCommand, UpdateCommand, InsertCommand, DeleteCommand를 포함한다. DataSet을 채우기 위해서 SelectCommand를 사용하고, 다른 나머지 세 개의 객체는 변경 내용을 다시 데이터 소스에 전달할 때 사용한다.
Microsoft ActiveX Data Objects(ADO)
기능적인 측면에서, Connection과 Command 객체는 해당되는 ADO 및 대응되는 객체와 어느 정도 동일하다(주요한 차이점은 서버측 커서가 제동되지 않는다는 것이다.) 반면에, DataReader 함수는 소방 호수 커서와 같다(전방향 읽기 전용의 특성으로 인하여), ADO에서 DataAdapter와 DataSet은 동일한 것이 없다.
DataSet
DataSet은 데이터를 나타내기 위한 메모리 상주형 데이터이다. DataSet의 구조는 아래 그림과 같으며, 테이블과 테이블 사이의 관계로 구성된 관계형 데이터베이스를 간단히 나타낸 형태와 같다고 볼 수 있다. DataSet이 항상 데이터 소스와 연결되어 있지 않다는 것을 이해하는 것이 중요하다. DataSet이 가지고 있는 데이터를 어디에서 가져왔는지 알지 못하지만, 실제적으로는 여러 데이터 소스의 데이터를 포함할 수 있다.
DataSet은 DataTableCollection과 DataRelationCollection이라는 두 개의 주요한 객체로 구성된다. DataTableCollecton은 0개 또는 그 이상의 DataTable객체를 포함한다. 그리고 DataTable은 차레로 Columns, Rows, Constraints의 세 개의 컬렉션으로 구성되어 있다. DataRelationCollection은 0개 또는 그 이상의 DataRelation을 포함한다.
DataTable의 Columns 컬렉션은 DataTable을 구성하는 열(Column)을 정의한다. 그리고 ColumnName과 DataType속성, DataColumn의 속성을 사용해서, 널을 허용할 것인지 말 것인지(AllowDBNull)와 최대값의 길이(MaxLength), 그리고 값을 계산하기 위한 수식(Expression)등을 정의할 수 있다.
DataTable의 Rows 컬렉션(비어 있을 수도 있다.)은 Columns 컬렉션으로 정의된 실제 데이터를 포함한다. DataTable은 각 행(Rows)에 대해서 원래 값(original), 현재 값(current)_, 제안된 값(proposed)을 유지한다. 이와 같은 기능으로 인해 프로그래밍 작업이 매우 간단해지는 것을 알게 될 것이다.
DataTable의 Constraints 컬렉션은 0개 또는 1개 이상의 Constraint를 포함한다. 마치 관계형 데이터베이스와 같이, Constraints는 데이터의 무결성을 유지 관리하기 위해 사용된다. ADO.NET은 아래와 같은 두 종류의 제약 조건(Constraint)을 지원한다.
ForeignKeyConstraints : 관계 무결성을 유지한다(즉, 자식 행은 고아가 되지 않는다는 것을 보장)
UniqueConstraints : 데이터 무결성을 유지한다(중복된 행이 테이블에 포함되지 않는다는 것을 보장)
또한 DataTable의 PromaryKey 속성을 이용해서 개체의 무결성을 보장할 수 있다(즉, 각 행의 유일성을 보장한다.)
마지막으로, DataSet의 DataRelationCollection은 0개 또는 그 이상의 DataRelation을 포함한다. DataRelation은 한 테이블의 마스터(부모) 행으로 다른 테이블의 관련 행을 간단히 검색할 수 있도록 프로그램적인 인터페이스를 제공한다. 예를 들어, 주문(Order)이 있다면, DAtaRelation으로 관련된 주문 상세 목록(OrderDetails) 행을 쉽게 뽑아 낼 수 있다. (하지만, DataRelation 그 자체는 관계에 대한 무결성을 보장해 주지 않는다).