2009-06-10 1 views
4

저는 QueriesTableAdapter가있는 DataSet을 가지고 있습니다. SqlCommand.CommandTimeout을 제어하기 위해 ChangeTimeout이라는 공용 메서드로 QueriesTableAdapter라는 부분 클래스를 추가했습니다.Control TableAdapter 명령 시간 초과 전체적으로

partial class QueriesTableAdapter 
{ 
    public void ChangeTimeout(int timeout) 
    { 
     foreach (System.Data.SqlClient.SqlCommand cmd in CommandCollection) 
     { 
      cmd.CommandTimeout = timeout; 
     } 
    } 
} 

내가 가지고있는 모든 데이터 세트에는 QueriesTableAdapter가 있으며, 실행하기 전에 CommandTimeout을 설정할 수 있습니다.

"QueriesTableAdapter"가 DataSet 디자이너에서 이름이 지정 되었기 때문에 대부분의 경우에 잘 작동합니다. 내가 실행중인 문제는 유일하게 명명 된 TableAdapters입니다. 예를 들어 Person이라는 DataTable과 PersonTableAdapter라는 TableAdaper가있는 경우 QueriesTableAdaper 클래스를 작성한 것과 같은 방식으로 PersonTableAdapter 부분 클래스를 작성해야합니다. 고유 한 TableAdapter 이름을 가진 수백 개의 DataTable이 있습니다. 나는 그것들 각각에 대해 부분적인 클래스를 만들고 싶지 않다. 전역 클래스에서 부분 클래스의 기본 SqlCommand 개체를 얻으려면 어떻게해야합니까?

답변

11

을 반환 답변/수입 2ns의에 CommandCollection 객체 에 사용되어야 할 네임 스페이스 첫번째 대답에 몇 가지 문제 을주고, 내 어댑터의 모두를 시도했다 .selectcommand는 null 이었기 때문에 CommandCollection 객체를 대신 사용해야하므로 위의 이전 대답을 기반으로 작은 변경 사항을 게시 할 것입니다.

은 다음과 같습니다

using System.ComponentModel; 
using System.Reflection; 

코드 :

private void ChangeTimeout(Component component, int timeout) 
     { 
      if (!component.GetType().Name.Contains("TableAdapter")) 
      { 
       return; 
      } 

      PropertyInfo adapterProp = component.GetType().GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); 
      if (adapterProp == null) 
      { 
       return; 
      }   

      SqlCommand[] command = adapterProp.GetValue(component, null) as SqlCommand[]; 

      if (command == null) 
      { 
       return; 
      } 

      command[0].CommandTimeout = timeout;    
     } 
+0

우수! 나는 똑같은 문제가 있었다. 귀하의 솔루션이 작동합니다. –

+0

마지막 줄 명령 [0] .CommandTimeout = timeout; 다음과 같이 TableAdapter에서 여러 메서드를 제공합니다. foreach (명령에서 SqlCommand sc) { sc.CommandTimeout = timeout; } – riaandelange

3

생성 된 모든 TableAdapter는 Component에서 상속됩니다. 따라서 어댑터 속성을 추출하는 반사를 사용하여이 같은 방법을 쓸 수있다 :

private void ChangeTimeout(Component component, int timeout) 
    { 
     if (!component.GetType().Name.Contains("TableAdapter")) 
     { 
      return; 
     } 

     PropertyInfo adapterProp = component.GetType().GetProperty("Adapter", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); 
     if (adapterProp == null) 
     { 
      return; 
     } 

     SqlDataAdapter adapter = adapterProp.GetValue(component, null) as SqlDataAdapter; 
     if (adapter == null) 
     { 
      return; 
     } 

     adapter.SelectCommand.CommandTimeout = timeout; 
    } 

을 당신은 다음과 같이 호출 할 수 있습니다

MyTableAdapter ta = new MyTableAdapter(); 
this.ChangeTimeout(ta,1000); 

을 내가 있으리라 믿고있어 당신이 사용하고 있기 때문에 형식화 된 DataSet은 여전히 ​​.NET 2.0에 있으므로 확장 메서드를 만드는 것을 방해하지 않았습니다.

+0

BFree을, 나는이 방법을 추가 할 수

대신 서명 호출자에 BFree의 방법

? –

+0

어디에서나 원하는 것이 있습니다.이상적으로는 정적 헬퍼 클래스를 만들어이 클래스의 정적 메서드로 추가하는 것이 좋습니다. – BFree

+0

내 대답은 방법을 넣을 위치에 대한 대체 옵션입니다. – Alex

0

나는 옵션과 adapter.SelectCommand 어떤 이유로 null 값

+0

http://forums.asp.net/t/1447323.aspx –

1

BFree 및 마크의 유사한 솔루션은 반사와 함께 잘 작동합니다. 아래 코드는 좀 더 정교한 코드입니다.

TableAdapter가 DataSet 디자이너에서 사용하는 기본 클래스를 변경할 수도 있습니다. TableAdapter의 기본 클래스를 MyTableAdapterBaseClass 또는 이와 유사한 것으로 변경하여 필요한 기능을 제공 할 수 있습니다. '파일에서 찾기'를 수행하고 DataSets의 .xsd 파일을 대체하여 모든 TableAdapter에서이 변경을 신속하게 수행 할 수 있습니다. 당신이 다음 서명 호출 수신자 TableAdapter에의 기본 클래스의 메소드 만들 수 있습니다

private void ChangeTimeout(Component component, int timeout) 

:

public void ChangeTimeout(int timeout)