닷넷에서는 DB를 어떤 것으로 불러오든 기본적으로 'SqlDataReader'라고 보시는 것이 맞습니다.
리턴값은 다르지만 데이터리더(DataReader)로 읽어 들인 후 나머지 작업(한 줄만 뽑아 문자열로 리턴한다던가 하는 작업)이 가능하니까요.
문제는 'SqlDataReader'라는 녀석은 테이블의 스키마 정보나 데이터를 다 가지고 있지만 가공 안 한체로 들어있어서 그냥 사용하기에는 여러 가지로 번거롭습니다.
그래서 보통은 'List<T>'나 'DataSet'으로 변환하여 사용하죠.
'List<T>'로 변환하는 방법은 한가지뿐이 없습니다.
직접 반복문을 이용하여 바인딩하는 것입니다.
'DataSet'이나 'DataTable'의 경우 두 가지 방법이 있습니다.
'List<T>'와 같이 직접 바인딩하거나 'SqlDataAdapter'를 이용하는 방법입니다.
'List<T>', 'DataSet', 'DataTable'등 어떤 것이든 가능합니다.
원한다면 2중 배열에도 바인딩이 가능 합니다.
직접 바인딩의 장점은 자신이 원하는 데로 바인딩할 수 있고 데이터를 넣는 과정에서 다른 문자열로 교체(컨버팅)이 가능합니다.
/// <summary>
/// sql처리를 위해 뒷부분에 해당하는 동작을 하는 메소드입니다.
/// sql처리 결과를 통체로 넘겨줍니다. 테이블 형태로 받을때 사용합니다.
/// SqlDataReader를 직접받아 처리 하도록 합니다.
/// </summary>
/// <param name="dtData">리턴할 데이터</param>
/// <returns>성공여부</returns>
private bool SQL_Execute_Body(ref DataTable dtData)
{
bool bReturn = true;
SqlDataReader sqlData;
try
{
this.commSql.Connection.Open(); //커낵션을 연다.
sqlData = commSql.ExecuteReader(); //쿼리를 실행한다.
//컬럼을 만들기 위해 스키마 테이블을 생성합니다
DataTable dtSchemaTable = sqlData.GetSchemaTable();
//추가용 컬럼
DataColumn dcData = null;
//추가용 로우
DataRow drData = null;
//리턴할 데이터를 초기화 해준다.
dtData = new DataTable();
//스키마를 가지고 테이블을 만들어 줍니다.
foreach (DataRow drColumn in dtSchemaTable.Rows)
{
//스키마로 받아온 데이터로 컬럼 데이터를 생성합니다.
dcData = new DataColumn(drColumn["ColumnName"].ToString(), (Type)drColumn["DataType"]);
//리턴할 데이터에 컬럼을 생성해 줍니다.
dtData.Columns.Add(dcData);
}
//생성한 테이블에 데이터를 넣습니다.
while (sqlData.Read())
{
//테이블에 맞게 로우를 생성해주고
drData = dtData.NewRow();
//생성한 로우에 데이터를 채우고
for (int i = 0; i < sqlData.FieldCount; i++)
{
drData[i] = sqlData.GetValue(i);
}
//생성한 로우를 추가 해줍니다.
dtData.Rows.Add(drData);
}
this.commSql.Connection.Close(); //커낵션 닫는다.
}
catch
{
//에러가 나면 실패다.
bReturn = false;
this.commSql.Connection.Close(); //커낵션 닫는다.
}
return bReturn;
}
참~ 복잡하죠? ㅎㅎㅎ
이 방법은 'DataSet', 'DataTable'을 바인딩 할 수 있습니다.
/// <summary>
/// sql처리를 위해 뒷부분에 해당하는 동작을 하는 메소드입니다.
/// sql처리 결과를 통체로 넘겨줍니다. 테이블 형태로 받을때 사용합니다.
/// SqlDataReader를 직접받아 처리 하도록 합니다.
/// </summary>
/// <param name="dtData">리턴할 데이터</param>
/// <returns>성공여부</returns>
private bool SQL_Execute_Body2(ref DataTable dtData)
{
SqlDataAdapter Adapter = new SqlDataAdapter(this.commSql);
Adapter.Fill(dtData);
return true;
}
참 쉽죠?
이 방법은 리턴온 데이터 테이블을 그대로 출력해준다는 장점이자 단점이 있습니다.
만약 원하는 형태가 있다면 한 번 더 변환을 해야하기 때문입니다.
하지만 간단한 방법이므로 쉽게 사용할 수 있습니다.
리스트야 그렇다 치지만 데이터셋은 왜 아답터 없이 바인딩이 안되는지 잘 모르겠습니다.
내부적으로는 어차피 반복문 돌려서 작업할 텐데 말이죠..