0

我正在尝试更新我在 DataSet(XSD 文件)中创建的 QueriesTableAdapter 中每个查询的连接字符串。我已经制作了尝试通过反射来做到这一点的方法(我有一个使用表适配器的类似方法)但是它似乎无法访问查询。这是我所做的方法:

        /// <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”的方法,以便我可以动态更改连接?

4

2 回答 2

0

据我所知,CommandCollection 属性是受保护的;试试这个:

GetProperty( "CommandCollection", BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic )
于 2013-02-20T12:07:30.397 回答
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());
    }
}
于 2013-02-22T10:47:38.747 回答