简体   繁体   English

通过多个动态控件运行查询 c# WinForms

[英]Running Query through multiple Dynamic Controls c# WinForms

I have created a tool which loops around all listed databases and executes a SQL Query one at a time.我创建了一个工具,它循环所有列出的数据库并一次执行一个 SQL 查询。 I've dynamically created the same controls in a new tab when you click on the New Query button, to allow me to run different queries at the same time.当您单击“新建查询”按钮时,我已经在新选项卡中动态创建了相同的控件,以允许我同时运行不同的查询。

I have an execute button which will execute the selected script.我有一个执行按钮,它将执行选定的脚本。 My problem is that it means my query variable will change depending if I execute another Script.我的问题是这意味着我的查询变量将根据我是否执行另一个脚本而改变。

This is how I find my controls这就是我找到控件的方式

private void findControls()
{
    tp = metroTabControl1.SelectedTab;
    s = ((SplitContainer)tp.Controls["SplitContainer" + tp.Name.ToString()]);
    tc = ((MetroTabControl)s.Panel2.Controls["AllResults" + tp.Name.ToString()]);
    tpResults = ((TabPage)tc.TabPages["Results" + tp.Name.ToString()]);
    tpMessages = ((TabPage)tc.TabPages["Messages" + tp.Name.ToString()]);

    dgvResults = ((DataGridView)tpResults.Controls["dgv" + tp.Name.ToString()]);
    tbMessages = ((MetroTextBox)tpMessages.Controls["Messages" + tp.Name.ToString()]);
    labCount = ((MetroLabel)s.Panel2.Controls["Progress" + tp.Name.ToString()]);
    tbQuery = ((MetroTextBox)s.Panel1.Controls["SQLQueryText" + tp.Name.ToString()]);
}

On the Execution, I create the BackgroundWorker and I set the Query在执行时,我创建了BackgroundWorker并设置了查询

BackgroundWorker bgwExec = new BackgroundWorker();
bgwExec.WorkerReportsProgress = true;
bgwExec.WorkerSupportsCancellation = true;

bgwExec.DoWork += BgwExec_DoWork;
bgwExec.ProgressChanged += BgwExec_ProgressChanged;
bgwExec.RunWorkerCompleted += BgwExec_RunWorkerCompleted;

findControls();
query = tbQuery.Text;

In the For loop, it'll run the query over all the databases, the issue though is that if I execute another query, then the BackgroundWorker will start running a different query.在 For 循环中,它将对所有数据库运行查询,但问题是如果我执行另一个查询,那么BackgroundWorker将开始运行不同的查询。

for (int i = 0; i < dtDBList.Rows.Count; i++)
{
    if (bgwExec.CancellationPending == true)
    {
        e.Cancel = true;
        return;
    }
    try
    {
        string server = dtDBList.Rows[i]["server"].ToString();
        string database = dtDBList.Rows[i]["db"].ToString();
        dtResults = eq.SelectStatementResults(query, server, database, iuser, ipass, dtResults);
        ds.Tables.Add(dtResults);
        progress += 1;
        bgwExec.ReportProgress(progress);
        sb = eq.sb;

        log.Info("Executed Script on " + database);
        log.Info(query);
    }
    catch (Exception err)
    {
        log.Error("Failed to execute script " + err.Message);
        progress += 1;
        errorCount += 1;
        bgwExec.ReportProgress(progress);
    }
}

Do you know of any way I can get around this?你知道我有什么办法可以解决这个问题吗?

I've tried using a dictionary, but then I still don't know how I would pull the correct value from the dictionary...我试过使用字典,但我仍然不知道如何从字典中提取正确的值......

Thanks in advance提前致谢

You can use the dictionary in this way:你可以这样使用字典:

private readonly Dictionary<BackgroundWorker, string> _queries = new Dictionary<BackgroundWorker, string>();

When creating a new BW, add it with its query to the dictionary:创建新 BW 时,将其与查询一起添加到字典中:

_queries.Add(bgwExec, tbQuery.Text);

On the BW events handlers, convert sender object to BackgroundWorker and use it to retrieve its query from the dictionary, something like this:在 BW 事件处理程序上,将sender object 转换为BackgroundWorker并使用它从字典中检索其查询,如下所示:

if (_queries.TryGetValue((BackgroundWorker)sender, out string query)) {
  // Do what you need with the query
}
else {
  // not in dictionary
}

Don't forget also to remove it from dictionary when not needed anymore so you don't leak it:不要忘记在不再需要时将其从字典中删除,以免泄漏:

_queries.Remove(bgwExec);

A more robust way to do it would be creating a class that encapsulates both BW and query, being responsible for the executing logic, so you use a List of instances of that class instead of a dictionary.一种更强大的方法是创建一个 class 封装 BW 和查询,负责执行逻辑,因此您使用该 class 的实例列表而不是字典。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM