c\#SqlDataAdapter 의 Fill 은 어떻게 실현 되 었 습 니까?
7188 단어 c#SqlDataAdapterfill이루어지다
최근 에 여러 가지 이유 로 직장 을 바 꾸 었 습 니 다.주요 사물 함 에 있 는 회사 에 갔 습 니 다.재 미 있 는 것 은 사물 함 에 있 는 단말 기 는 wpf 로 쓴 것 입 니 다.코드 도 오랫동안 수리 하지 않 은 셈 이 고 기술 빚 이 매우 무 거 운 것 같 습 니 다.며칠 전에 bug 를 디 버 깅 할 때 이런 코드 를 보 았 습 니 다.
var dt = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(new SqlCommand());
adapter.Fill(dt);
낯 이 익 지 않 습 니까?아마 당신 도 몇 년 동안 보이 지 않 았 을 것 입 니 다.그때 데이터 베 이 스 를 통 해 데 이 터 를 얻 기 위해 첫 번 째 방법 은SqlDataReader
한 줄 한 줄 로 데이터 베 이 스 를 읽 고 Reader 의 close 문 제 를 걱정 해 야 한 다 는 것 을 기억 합 니 다.두 번 째 방법 은 번 거 로 움 을 피하 기 위해 본 편 에서 말 한SqlDataAdapter
간단 하고 거 칠 며 아무것도 신경 쓰 지 마 세 요.참,저 처럼 이 방법 에 대해 궁금 하 시 는 지 모 르 겠 어 요.그것 은 어떻게 데 이 터 를 DataTable 에 끼 워 넣 었 습 니까?SqlDataReader 도 쓰 나 요?그리고Fill
그리고 여러 가지 확장 방법 이 있 습 니 다.하하,이 편 은 하나씩 이 야 기 를 나 누 면 경전 을 돌 이 켜 보 는 것 이 라 고 생각 합 니 다!2.Fill 방법 에 대한 탐구
1.dnspy 로 Fill 원본 보기
dnspy 도 구 는 GitHub 위 에 가서 다운로드 할 수 있 습 니 다.여 기 는 구체 적 으로 말 하지 않 겠 습 니 다.그 다음 에 Fill 의 최상 위 를 따라 잡 아 보 세 요.다음 코드 는 다음 과 같 습 니 다.
public int Fill(DataTable dataTable)
{
IntPtr intPtr;
Bid.ScopeEnter(out intPtr, "<comm.DbDataAdapter.Fill|API> %d#, dataTable
", base.ObjectID);
int result;
try
{
DataTable[] dataTables = new DataTable[]
{
dataTable
};
IDbCommand selectCommand = this._IDbDataAdapter.SelectCommand;
CommandBehavior fillCommandBehavior = this.FillCommandBehavior;
result = this.Fill(dataTables, 0, 0, selectCommand, fillCommandBehavior);
}
finally
{
Bid.ScopeLeave(ref intPtr);
}
return result;
}
위의 코드 가 가장 중요 한 곳 은 IDbCommand selectCommand=this. 입 니 다.IDbDataAdapter.SelectCommand; 이곳 의 SelectCommand 는 어디에서 왔 습 니까?new SqlDataAdapter 에서 입력 한 구조 함수 SqlCommand 입 니 다.다음 코드 는 다음 과 같 습 니 다.
public SqlDataAdapter(SqlCommand selectCommand) : this()
{
this.SelectCommand = selectCommand;
}
그리고 this.Fill 방법 을 계속 내 려 다 보 세 요.코드 를 간소화 한 후 다음 과 같 습 니 다.
protected virtual int Fill(DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior)
{
result = this.FillInternal(null, dataTables, startRecord, maxRecords, null, command, behavior);
return result;
}
위의 이 코드 는 할 말 이 없습니다.this.Fill Internal 방법 을 계속 추적 하고 간소화 한 후에 다음 과 같 습 니 다.
private int FillInternal(DataSet dataset, DataTable[] datatables, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
{
int result = 0;
try
{
IDbConnection connection = DbDataAdapter.GetConnection3(this, command, "Fill");
try
{
IDataReader dataReader = null;
try
{
dataReader = command.ExecuteReader(behavior);
result = this.Fill(datatables, dataReader, startRecord, maxRecords);
}
finally
{
if (dataReader != null) dataReader.Dispose();
}
}
finally
{
DbDataAdapter.QuietClose(connection, originalState);
}
}
finally
{
if (flag)
{
command.Transaction = null;
command.Connection = null;
}
}
return result;
}
여러분 은 위의 코드 를 자세히 연구 할 수 있 습 니 다.매우 재 미 있 습 니 다.적어도 다음 과 같은 두 가지 정 보 를 얻 을 수 있 습 니 다.
protected virtual int Fill(DataTable[] dataTables, IDataReader dataReader, int startRecord, int maxRecords)
{
try
{
int num = 0;
bool flag = false;
DataSet dataSet = dataTables[0].DataSet;
int num2 = 0;
while (num2 < dataTables.Length && !dataReader.IsClosed)
{
DataReaderContainer dataReaderContainer = DataReaderContainer.Create(dataReader, this.ReturnProviderSpecificTypes);
if (num2 == 0)
{
bool flag2;
do
{
flag2 = this.FillNextResult(dataReaderContainer);
}
while (flag2 && dataReaderContainer.FieldCount <= 0);
}
}
result = num;
}
return result;
}
위의 코드 를 통 해 알 수 있 듯 이 dataReader 는 DataReader Container 에 봉인 되 어 있 습 니 다.FillNextResult 로 여러 개의 datatable 대상 을 만 들 수 있 습 니 다.마지막 으로 DataTable 을 채 우 는 것 입 니 다.물론 dataReader.Read()를 사용 하 는 것 입 니 다.믿 지 않 으 면 계속 안 으로 쫓 아 갈 수 있 습 니 다.다음 코드:
private int FillLoadDataRow(SchemaMapping mapping)
{
int num = 0;
DataReaderContainer dataReader = mapping.DataReader;
while (dataReader.Read())
{
mapping.LoadDataRow();
num++;
}
return num;
}
여기 서 DataReader 의 성능 은 Fill 에서 DataTable 까지 의 성능 보다 훨씬 높 을 것 입 니 다.그래서 유연성 과 둘 사이 에서 선택 하 셨 습 니 다.2.Fill 의 기타 과부하 방법
방금 소개 한 것 은 DataTable 매개 변 수 를 가 진 리 셋 입 니 다.사실은 이것 을 제외 하고 네 가지 리 셋 방법 이 있 습 니 다.다음 과 같 습 니 다.
public override int Fill(DataSet dataSet);
public int Fill(DataSet dataSet, string srcTable);
public int Fill(DataSet dataSet, int startRecord, int maxRecords, string srcTable);
public int Fill(int startRecord, int maxRecords, params DataTable[] dataTables);
1.startRecord 와 max Records말 그대로 지 정 된 위치(startRecord)부터 읽 고 max Records 항목 의 기록 을 가장 많이 읽 으 려 는 것 입 니 다.이해 하기 쉽 습 니 다.reader()는 앞으로 만 읽 는 것 을 알 고 있 습 니 다.그리고 소스 밑 에 어떻게 실현 되 는 지 함께 보 겠 습 니 다.
위의 그림 에서 보 듯 이 아주 간단 합 니 다.startRecord 개 reader()를 차 버 리 고 앞으로 만 읽 고 최대 max Records 개의 기록 을 얻 습 니 다.
2.dataSet 과 srcTable
여기 srcTable 이 무슨 뜻 이 죠?vs 에서 보면 이 렇 습 니 다:The name of the source table to use for table mapping.언뜻 봐 도 잘 모 르 겠 어 요.괜찮아 요.그냥 소스 코드 를 보면 돼 요.어차피 저도 테스트 안 했 어 요.헤헤.
위의 그림 에서 대략적인 뜻 은 dataset 의 datatable 에 이름 을 지어 주 는 것 임 을 알 아야 합 니 다.예 를 들 어 name=학생 표,database 의 table name 은 다음 과 같 습 니 다.학생 표,학생 표 1,학생 표 2.그러면 색인 으로 표 의 이름 을 얻 을 수 있 습 니 다.다음 코드 는 다음 과 같 습 니 다.
DataSet dataSet = new DataSet();
dataSet.Tables.Add(new DataTable(" "));
var tb = dataSet.Tables[" "];
총화이 편 은 이렇게 많은 이 야 기 를 나 누 었 습 니 다.몇 년 전의 호기심 을 풀 었 다 고 할 수 있 습 니 다.이 편 이 당신 에 게 도움 이 되 기 를 바 랍 니 다.
이상 은 c\#SqlDataAdapter 의 Fill 이 어떻게 실현 되 는 지 에 대한 상세 한 내용 입 니 다.c\#SqlDataAdapter 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.