ADO.NET(DB자체는 동시성이라는 문제점을 항상 있다)
1. 연결지향(전화)
- Connection
- Command
- DataReader
- DataAdapter(연결정보 + 결과셋 + 테이블 + 컬럼 + 레코드 정보를 가지고 있다.)
2. 비연결 지향 ( 동시성을 버리고서라도 속도면에서 엄청난 이득이 있어서 비연결 지향을 쓴다)
- DataSet(비중이 굉장히 높다!!!)
어뎁터라는 속성으로 디비에 접근해서 결과셋을 데이터베이스에 얻어 메모리에 적재한다.
응용 프로그램이 죽으면 메모리에 있는 영역에 결과셋이기 때문에 사라진다.
속도 상으로 디비에 접근하여 연결지향적으로 접근하면 속도가 느리지만 , 비연결 지향으로 접근할때는 메모리에서 값을 얻어오는 것이기 때문에 속도면에서 차이가 엄청난다.
- 실데이터가 삭제되거나 업데이트가 된경우 DataSet에 메모리에 상주 된것은 동기화 되어있지 않은 상태이므로 단점이 생긴다.
- 처음에 가져온 데이터를 보는 용도로만 사용한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AdoConsole
{
class EX16_DataSet
{
static void Main(string[] args)
{
string query = "SELECT * FROM tblAddress";
//1. 어댑터 생성 = 연결객체(SqlConnection) + 명령객체(SqlCommand)
// query : SqlCommand 담당이었다.
// ADONET : sqlConnection
// SqlDataAdapter : 내부적으로 커넥션 객체가 하나 만들어지고, 커맨드 객체도 하나만들어진다. 2개의 객체를 감싸주는 컨테이너이다.
// - 눈에 안보이게 캡슐화 되어 있는 상태이다.
//2. 데이터셋 생성(복사되어진 결과셋을 저장할 로컬의 메모리 공간) = 로컬 DB(SQL SERVER의 데이터베이스와 같음)
SqlDataAdapter adapter = new SqlDataAdapter(query, Settings1.Default.ADONET);
//데이터베이스 = 테이블 집합(컬럼집합 + 레코드집합) = DataSet
DataSet ds = new DataSet();
//3. 복사!!
// - adapter 통해서 ds에 데이터를 채워넣기
//복사명령 db접근, 쿼리문 실행, 데이터결과셋 생성, 결과값 ds에 저장 모든게 캡슐화 되어있다.
// DB 접속중이지 않다.
adapter.Fill(ds);//메소드 안에서만 DB 접속중
// DB 접속중이지 않다.
//4. 가져온 데이터를 사용(주목적!!!!!!!)
// - DB와의 연결은 끊긴 상태 *****************비연결 지향
//DataSet의 구조
// - DataTable의 집합 : 테이블
// - DataRow의 집합 : 레코드
// - DataColumn : 컬럼
//현재 로컬DB인 ds안에는 테이블 1개가 있습니다.
Console.WriteLine(ds.Tables.Count);
//ds안의 테이블 접근 방법
//1. 이름으로 접근
//2. 인덱스로 접근
//ds.Tables["tblAddress"] //X
//c#에서 만든 테이블은 이름을 새로 지정해 주어야 한다.
ds.Tables[0].TableName = "tblAddress";//원본이름과 같은 형태로 주는것이 좋다.
//이름을 주고 난뒤에 이름으로 접근 가능!!
DataTable tblAddress = ds.Tables["tblAddress"];
//DataTable내의 데이터 접근
//tblAddress.Rows : 행(레코드)의집합
for (int i = 0; i < tblAddress.Rows.Count; i++)
{
DataRow row = tblAddress.Rows[i];//한행
//이론상 경제적이고 속도가 엄청 빠르다.
Console.WriteLine(row["name"].ToString());
Console.WriteLine(row["age"].ToString());
}
//컬렉션 <-> SqlDataReader
//4번째 레코드의 전화번호 바로접근 가능!!!
Console.WriteLine(tblAddress.Rows[3]["tel"].ToString());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace AdoConsole
{
class Ex17_DataSet
{
static void Main(string[] args)
{
//DB -> 테이블 n개
//DataSet -> DataTable n개
M1();
}
private static void M1()
{
//1. 어뎁터
SqlConnection con = new SqlConnection(Settings1.Default.ADONET);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM tblAddress";
//원래 adapter가 알아서 코넥하고 커맨드하는데 현재 예제는 응용하기 위해서 직접넣어주었다.
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
//2. 데이터셋
DataSet ds = new DataSet();
//3. 채워넣기
//이름을 같이 한번에 넣어주자
adapter.Fill(ds, "tblAddress");
Console.WriteLine(ds.Tables.Count);
//4. 또 다른 결과셋을 가져오기 멜론 테이블 접근
// cmd(con) -> adapter소속
cmd.CommandText = "SELECT * FROM tblMelon";
//5. 채워넣기(횟수에 상관없이 계속 채워넣기가 가능하다)
adapter.Fill(ds, "tblMelon");
Console.WriteLine(ds.Tables.Count);
//- 되도록 여러개의 테이블은 채워넣지 않도록 한다 -> c# 동장죽인 컴퓨터의 메몰 -> 테이블이 많아지면 -> 메모리 부족..
//6. 탐색
for (int i = 0; i < ds.Tables["tblAddress"].Rows.Count; i++)
{
Console.WriteLine(ds.Tables["tblAddress"].Rows[i]["name"].ToString());
}
foreach (DataRow row in ds.Tables["tblMelon"].Rows)
{
Console.WriteLine(row["singer"].ToString());
}
}
}
}