2013-02-20 65 views
0

我正在嘗試更新QueriesTableAdapter中每個查詢的連接字符串,這些查詢是在DataSet(XSD文件)內部創建的。我已經通過反射(我有一個類似的方法與表適配器一起工作)嘗試做到這一點,但它似乎無法訪問查詢。以下是我所做的方法:更改查詢表適配器數據庫連接

 /// <summary> 
     /// Changes the database all the queries in a queries table adapter connect to 
     /// </summary> 
     /// <typeparam name="IQA">The type of the queries table adapter</typeparam> 
     /// <param name="InstanceQueriesAdapter">The instance of the queries table adapter</param> 
     /// <param name="sqlDatabaseName">The name of the database the queries table adapter queries should connect to</param> 
     public static void GetInstanceQueriesAdapter<IQA>(ref IQA InstanceQueriesAdapter, string sqlDatabaseName) 
     { 
      try 
      { 
       PropertyInfo qAdapterCommandCollection = InstanceQueriesAdapter.GetType().GetProperty("CommandCollection"); 

       if (qAdapterCommandCollection != null) 
       { 
        SqlCommand[] qaCC = (SqlCommand[])qAdapterCommandCollection.GetValue(InstanceQueriesAdapter, null); 

        foreach (SqlCommand singleCommand in qaCC) 
        { 
         SqlConnection newSQLConnection = singleCommand.Connection; 

         SqlConnectionStringBuilder csBulider = new SqlConnectionStringBuilder(newSQLConnection.ConnectionString); 

         csBulider.InitialCatalog = sqlDatabaseName; 

         newSQLConnection.ConnectionString = csBulider.ConnectionString; 

         singleCommand.Connection = newSQLConnection; 
        } 

        qAdapterCommandCollection.SetValue(InstanceQueriesAdapter, qaCC, null); 
       } 
       else 
       { 
        throw new Exception("Could not find command collection."); 
       } 
      } 
      catch (Exception _exception) 
      { 
       throw new Exception(_exception.ToString()); 
      } 
     } 

由於GetProperty方法返回null,因此失敗。然而,你可以在這裏看到的屬性確實存在:

1

這裏是從即時窗口輸出:

? InstanceQueriesAdapter.GetType().GetProperties() 
{System.Reflection.PropertyInfo[2]} 
    [0]: {System.ComponentModel.ISite Site} 
    [1]: {System.ComponentModel.IContainer Container} 
? InstanceQueriesAdapter.GetType().GetMethods() 
{System.Reflection.MethodInfo[14]} 
    [0]: {System.Object ImportProcess(System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Nullable`1[System.Guid], System.String ByRef)} 
    [1]: {Void add_Disposed(System.EventHandler)} 
    [2]: {Void remove_Disposed(System.EventHandler)} 
    [3]: {System.ComponentModel.ISite get_Site()} 
    [4]: {Void set_Site(System.ComponentModel.ISite)} 
    [5]: {Void Dispose()} 
    [6]: {System.ComponentModel.IContainer get_Container()} 
    [7]: {System.String ToString()} 
    [8]: {System.Object GetLifetimeService()} 
    [9]: {System.Object InitializeLifetimeService()} 
    [10]: {System.Runtime.Remoting.ObjRef CreateObjRef(System.Type)} 
    [11]: {Boolean Equals(System.Object)} 
    [12]: {Int32 GetHashCode()} 
    [13]: {System.Type GetType()} 

有誰知道的一種方式來獲得這種「CommandCollection」所以我可以動態改變連接?

回答

0

改變數據庫的工作代碼。還值得注意的是,連接的所有部分可以在這裏更改,如超時等。

/// <summary> 
/// Changes the database all the queries in a queries table adapter connect to 
/// </summary> 
/// <typeparam name="IQA">The type of the queries table adapter</typeparam> 
/// <param name="InstanceQueriesAdapter">The instance of the queries table adapter</param> 
/// <param name="sqlDatabaseName">The name of the database the queries table adapter queries should connect to</param> 
public static void GetInstanceQueriesAdapter<IQA>(ref IQA InstanceQueriesAdapter, string sqlDatabaseName) 
{ 
    try 
    { 
     FieldInfo qAdapterCommandCollection = InstanceQueriesAdapter.GetType().GetField("_commandCollection", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic); 
     MethodInfo initCC = InstanceQueriesAdapter.GetType().GetMethod("InitCommandCollection", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic); 

     if (qAdapterCommandCollection != null && initCC != null) 
     { 
      initCC.Invoke(InstanceQueriesAdapter, null); 

      IDbCommand[] qaCC = (IDbCommand[])qAdapterCommandCollection.GetValue(InstanceQueriesAdapter); 

      foreach (SqlCommand singleCommand in qaCC) 
      { 
       SqlConnection newSQLConnection = singleCommand.Connection; 

       SqlConnectionStringBuilder csBulider = new SqlConnectionStringBuilder(newSQLConnection.ConnectionString); 

       csBulider.InitialCatalog = sqlDatabaseName; 

       newSQLConnection.ConnectionString = csBulider.ConnectionString; 

       singleCommand.Connection = newSQLConnection; 
      } 

      qAdapterCommandCollection.SetValue(InstanceQueriesAdapter, qaCC); 
     } 
     else 
     { 
      throw new Exception("Could not find command collection."); 
     } 
    } 
    catch (Exception _exception) 
    { 
     throw new Exception(_exception.ToString()); 
    } 
} 
0

從我可以看到,CommandCollection屬性被保護;試試這個:

GetProperty("CommandCollection", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic) 
+0

謝謝,這讓我得到了CommandCollections。但是,當我嘗試將屬性設置爲「未找到屬性集方法」時,我現在正在收到錯誤消息。我嘗試將一些BindingFlags放入SetProperty方法中,但它不起作用。有任何想法嗎? – Wizardskills 2013-02-20 13:34:12

+0

這很可能是該物業沒有一個二傳手。在這種情況下,您應該通過**添加/清除/刪除**方法來處理集合。另外,從理論上講,由於財產背後有一個領域,您可以改爲訪問該領域。就我個人而言,我永遠不會替換沒有setter的集合,更不用說整個時髦的東西了....如果字段受到保護,而類不是最終的,我會探索,如果有可能性使用子類型,這會給你「合法」訪問受保護的財產,等等。 – 2013-02-20 14:57:49

+0

使用該字段實際上工作:)。我用我的工作代碼編輯了我的問題。 – Wizardskills 2013-02-22 10:43:32