型付 DataSet의 TableAdapter의 기본 클래스를 변경 하는

페이지 생성 날짜 :

型付 DataSet 생성 및 생성 된 코드

型付 DataSet을 사용 하면 SQL을 기반으로 하는 각 열의 형식 정보를 사용 하 여 DataTable을 창조 할 수 있고, 型付 DataTable을 기반으로 DB와 데이터의 상호 작용을 단순화 하는 TableAdapter를 사용할 수 있습니다.

여기에서는 型付 DataSet을 만들 수는 없으므로 일단은 데이터베이스 및 테이블을 제공 하 고 있는 상황에서 DataSet을 퍼즐로 만들어 버려 보세요. 테이블 레이아웃도 원하는대로 수 없습니다.

먼저 프로젝트에 새 항목으로 DataSet를 추가 합니다. 이름은 뭐 든 좋지만 여기에 그대로 서 있습니다.

DataSet을 열고 디자이너에서 TableAdapter를 추가 합니다.

마법사에 따라 진행 및 DataTable 및 TableAdapter가 만들어집니다.

만든 DataTable, TableAdapter를 사용 하 여 데이터베이스에서 레코드를 검색 하 고 사용 하는 예로는 다음과 같은 형태가 될 것 이라고 믿습니다. (어디까지 나 일례입니다)

public Form1()
{
  InitializeComponent();

  using (var adapter = new 金額集計TestTableAdapter())
  {
    var table = adapter.GetData();

    foreach (var row in table)
    {
      Trace.WriteLine(string.Format("{0}:{1}", row.年月, row.金額));
    }
  }
}

일반적으로 DataSet를 사용 하는 프로젝트에는 테이블이 하나 없다는 것은 적게, 테이블 또는 여러 테이블을 결합 하 여 DataSet을 많이 만드는 것입니다. 이 경우 기부금 처리 기능 이라고 생각 합니다. 예를 들면 내부에 사용 되는 SQL을 동적으로 바꾸어 레코드 검색 조건을 바꾸는 등입니다.

그러나, 실은 DataSet에서 생성 된 TableAdapter 클래스는 자동으로 코드가 생성 되는 것으로 되어 있습니다. 또한이 TableAdapter 클래스는 Component 클래스에서 상속 하는 것으로 되어 있기 때문에, 진짜 공통적으로 사용할 수 있는 메서드와 속성은 없습니다. 메서드가 기본 클래스를 전달 하 여 TableAdapter에 관련 된 가능한 작업을 호출할 수 없습니다.

내부에서 사용 된 SQL 데이터베이스에 액세스 하는 데 사용 된 SqlDataAdapter는 protected로 선언 되어 있기 때문에 외부에서 만질 수 없습니다.

단지, protected로 선언 된 메서드 및 속성에 대해 선언 대로 TableAdapter 클래스를 상속 하는 클래스를 만들면 밟기도 하 고 또한 TableAdapter 클래스는 partial 한정자가 있으므로 다른 메서드 및 속성을 선언 하 고 프로세스를 확장할 수 있습니다. 다음 코드와 같이 새로운 속성을 만들어 내부 속성을 검색할 수 있습니다.

using System.Data.SqlClient;
namespace DataSetBaseAdapter {
    public partial class DataSet1 {
    }
}

namespace DataSetBaseAdapter.DataSet1TableAdapters
{
  public partial class 金額集計TestTableAdapter
  {
    public SqlDataAdapter InnerAdapter
    {
      get { return Adapter; }
    }
  }
}

실제로이 TableAdapter를 사용 하 여 확장 된 속성에 액세스할 수 있습니다.

그러나 내부 속성에 액세스할 수 있기 때문에 프로세스가 동일 하다는 것은 아니며, 역시 만든 DataSet에 대해 코드를 작성 해야 합니다.

TableAdapter의 기본 클래스를 변경 하는

앞서 언급 했 듯이 TableAdapter 클래스는 Component 클래스에서 상속 하는 때문에 작업을 유지 하기 어렵게 되어 있습니다. 만약 클래스가 상속 되는 코드 부분을 변경 해도 코드가 자동 생성 되어 다시 DataSet을 업데이트 하는 코드를 되돌립니다. 수 있는 별도의 파일에 interface를 상속 되는 partial 클래스를 작성할 수도 있습니다, 그러나 최후에 만든 TableAdapter 만큼 쓰지 않으면 안 되는 것 이기 때문에 별로 의미는 없습니다.

사실이 TableAdapter 상속 클래스를 변경 하는 메커니즘은 존재 합니다. 해당 단계에 대해 설명 하 고 싶습니다.

우선 상속 하려는 클래스를 만듭니다. TableAdapter는 원래 Component 클래스를 상속 하므로 클래스 에서도 Component 클래스에서 상속 해야 합니다. 여기에 공유 하고자 하는 코드를 작성 합니다만, 여기서는 일단 클래스만 생성 합니다. 네임 스페이스는 자신이 만든 것과 일치 해야 합니다.

using System.ComponentModel;

namespace DataSetBaseAdapter
{
  public class BaseAdapter : Component
  {
  }
}

그런 다음 DataSet 디자이너를 열어 만든 TableAdapter를 선택 합니다.

마우스 오른쪽 단추로 클릭 하 고 속성을 엽니다. BaseClass 라는 속성이 고 처음에는 「 System.ComponentModel.Component 」으로 설정 되어 있어야 합니다. 여기에 방금 만든 클래스를 무시 합니다. 이 경우 네임 스페이스를 포함 하 여 쓰고 있습니다.

저장 하면 TableAdapter의 기본 클래스를 변경 볼 수 있습니다. 이렇게 각 TableAdapter에 설정 하 여 일반 동작을 기본 클래스에 쓸 수 있게 됩니다.

예를 들면 내부 SQL 또는 SqlDataAdapter를 사용 하고자 한다면 다음과 같이 작성 합니다. 자동으로 만들어진 Adapter 나 CommandCollection는 어디까지 나 상속 된 클래스를 만들어 속성 이므로 상속에서 직접 만질 수 없습니다. 다음 코드에서는 리플렉션을 사용 하 여 액세스할 수 있도록 하 고 있습니다.

using System.ComponentModel;
using System.Data.SqlClient;
using System.Reflection;

namespace DataSetBaseAdapter
{
  public class BaseAdapter : Component
  {
    public SqlDataAdapter InnerAdapter
    {
      get
      {
        return (SqlDataAdapter)GetType().GetProperty("Adapter",
          BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this, null);
      }
    }

    public SqlCommand[] InnerCommandCollection
    {
      get
      {
        return (SqlCommand[])GetType().GetProperty("CommandCollection",
          BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this, null);
      }
    }
  }
}

실제로 TableAdapter를 사용 하 여 상속 된 클래스의 속성에 액세스할 수 있다는 것을 알 수 있습니다.