0

4 つの重いデータベース テーブル (それぞれ 3000 万行) があり、クエリは 4 つのテーブルすべてからデータを取得し、ユニオンを実行してすべてを結合しますが、クエリは多くの行 (最大 1000 行) を返しません。したがって、クエリ全体が完了するまでに 20 秒かかるとしましょう。テーブルごとに個別のクエリを作成し、非同期または TPL を使用してそれらを呼び出し、結果をビジネス オブジェクト (c# .Net 4.0) に結合してから返すことを考えています。 ASP.NET Web フォームに。

BeginExecuteReader と Task.Factory.StartNew を見てきましたが、すべてをまとめる方法がわかりません。以前に誰かがこのようなことをしたことがありますか? どうすればこれを行うことができますか?

4

1 に答える 1

0

私は最終的にこれを自分で行い、他の誰かがそれを必要とする場合はここに置きます.

DataTable dtReturn = new DataTable();
var connection = new SqlConnection((_connectionstring.IndexOf("MultipleActiveResultsets") == -1) ? _connectionstring + "MultipleActiveResultsets=True;" : _connectionstring);
try
{
    connection.Open();

    Task<DataTable>[] tasks = new Task<DataTable>[source.Rows.Count];
    for (int i = 0; i < source.Rows.Count; i++)
    {
        int s = Convert.ToInt32(source.Rows[i][0]);
        Task<DataTable> t = Task.Factory.StartNew(() =>
        {
            var command = connection.CreateCommand();
            command.CommandText = commandText;
            command.CommandType = CommandType.StoredProcedure;
            command.CommandTimeout = timeout;

            foreach (SqlParameter p in parms)
            {
                if (p.ParameterName == "@Sources")
                    command.Parameters.Add(new SqlParameter() { SqlDbType = System.Data.SqlDbType.Structured, ParameterName = p.ParameterName, Value = s.ToString().ToIDList() });
                else
                    command.Parameters.Add(new SqlParameter() { ParameterName = p.ParameterName, Value = p.Value });
            }
            var dr = command.ExecuteReader();
            command.Parameters.Clear();
            DataTable dt = new DataTable();
            if (dr.HasRows)
            {
                dt.Load(dr);
                dr.Close();
            }
            return dt;
        });
        tasks[i] = t;
    }

    Task.WaitAll(tasks);
    if (tasks.Length > 0)
    {
        bool isSchemaCloned = false;
        foreach (var t in tasks)
        {
            if (!isSchemaCloned && t.Result.Columns.Count > 0 )
            {
                dtReturn = t.Result.Clone();
                isSchemaCloned = true; 
            }

            foreach (DataRow r in t.Result.Rows)
            {
                dtReturn.Rows.Add(r.ItemArray);
            }
        }
    }
}
catch (Exception ex)
{
    throw ex;
}
finally
{
    if (connection.State != ConnectionState.Closed)
        connection.Close();
}

return dtReturn;
于 2013-09-17T16:46:55.433 に答える