2009-06-10 6 views
4

J'ai un DataSet avec un QueriesTableAdapter. Afin de contrôler le SqlCommand.CommandTimeout j'ai ajouté une classe partielle appelée QueriesTableAdapter avec une méthode publique appelée ChangeTimeout.Contrôle globalement de la commande TableAdapter

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

Pour chaque DataSet je qui a un QueriesTableAdapter, je peux mettre la CommandTimeout avant l'exécution.

using (NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter ta = 
new NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter()) 
{ 
    ta.ChangeTimeout(3600); 
    ta.DoSomething(); 
} 

Cela fonctionne bien dans la plupart des cas parce que le "QueriesTableAdapter" est nommé pour vous dans le concepteur DataSet. Le problème que je rencontre est le TableAdapters qui sont nommés de façon unique. Par exemple, si j'ai un DataTable appelé Person et un TableAdaper appelé PersonTableAdapter, je dois écrire une classe partielle PersonTableAdapter de la même manière que j'ai écrit la classe QueriesTableAdaper. J'ai des centaines de DataTables avec des noms TableAdapter uniques. Je ne veux pas créer une classe partielle pour chacun d'eux. Comment puis-je accéder aux objets SqlCommand sous-jacents d'une classe partielle de manière globale?

Répondre

11

pour une raison quelconque, mon adaptateur de .selectcommand était null, donc j'ai dû passer par l'objet CommandCollection à la place, donc j'ai pensé poster mon petit changement basé sur la réponse précédente ci-dessus.

comprend:

using System.ComponentModel; 
using System.Reflection; 

Code:

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

Excellent! J'ai eu le même problème. Votre solution fonctionne. –

+0

Remplacé la dernière commande de ligne [0] .CommandTimeout = timeout; avec ce qui suit pour prendre en charge plusieurs méthodes dans TableAdapter: foreach (commande SqlCommand sc) { sc.CommandTimeout = timeout; } – riaandelange

3

Tous les TableAdapters générés héritent de Component. Par conséquent, vous pourriez écrire une méthode de ce genre qui utilise la réflexion pour extraire la propriété de l'adaptateur:

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; 
    } 

Vous pouvez l'appeler comme ceci:

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

Je suppose que puisque vous utilisez DataSet tapé que vous êtes toujours en .NET 2.0, c'est pourquoi je n'ai pas pris la peine d'en faire une méthode d'extension.

+0

Bfree, où pourrais-je ajouter cette méthode ? –

+0

Partout où vous voulez vraiment.Idéalement, vous devez probablement créer une classe d'assistance statique et l'ajouter en tant que méthode statique dans cette classe. – BFree

+0

Une autre option pour savoir où placer la méthode est dans ma réponse. – Alex

0

J'ai essayé deux options et donnant quelques questions Le 1er réponse qui namespace doivent être importés/utilisés pour objet CommandCollection sur 2ns Réponse adapter.SelectCommand retourne la valeur null

+0

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

1

Bfree et des solutions similaires de marque fonctionnent bien avec la réflexion. Voici un léger raffinement qui, je pense, donne un code plus net.

Vous pouvez également modifier la classe de base utilisée par TableAdapter dans le concepteur DataSet. Vous pouvez modifier la classe de base de votre TableAdapter à MyTableAdapterBaseClass ou similaire pour fournir la fonctionnalité dont vous avez besoin. Vous pouvez faire ce changement rapidement sur tous vos TableAdapters en faisant un 'Find in Files' et le remplacer sur les fichiers .xsd de vos DataSets.

au lieu de la méthode de Bfree sur l'appelant à la signature:

private void ChangeTimeout(Component component, int timeout) 

vous pouvez créer une méthode sur la callee la classe de base de TableAdapter avec signature:

public void ChangeTimeout(int timeout) 
Questions connexes