c\#SqlDataAdapter 의 Fill 은 어떻게 실현 되 었 습 니까?

1.이야기 하기
최근 에 여러 가지 이유 로 직장 을 바 꾸 었 습 니 다.주요 사물 함 에 있 는 회사 에 갔 습 니 다.재 미 있 는 것 은 사물 함 에 있 는 단말 기 는 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;
		}
여러분 은 위의 코드 를 자세히 연구 할 수 있 습 니 다.매우 재 미 있 습 니 다.적어도 다음 과 같은 두 가지 정 보 를 얻 을 수 있 습 니 다.
  • 각 finally 에서 볼 수 있 듯 이 데이터 fill 이 datatable 에 들 어간 후에 데이터 베 이 스 를 조작 하 는 몇 가지 대상 Connection,Transaction,DataReader 가 모두 닫 힐 것 이 니 신경 쓸 필요 가 없습니다
  • this.Fill(datatables,dataReader,startRecord,maxRecords)에서 볼 수 있 습 니 다.바 텀 에서 의외 의 사고 가 발생 하지 않 는 것 도 dataReader.read()한 줄 한 줄 을 통 해 읽 고 DataTable 에 넣 었 습 니 다.그렇지 않 으 면 이 dataReader 를 가지 고 무엇 을 합 니까?못 믿 겠 으 면 계속 쫓 아 다 녀 도 돼.
  • 
    		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 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기