enter code here
Webappでは、異なるSQLサーバー上に全く同じテーブルスキーマを持つデータベースのインスタンスが5つあります。 これらの5つのデータベース/サーバーすべてに対してObjectcontextで使用可能なExecuteStoreQuery()メソッドを使用してSQLクエリ(またはクエリ)を並列に実行し、マージ結果を返したいとします。私は重複を気にしないので、すべてのDBのすべての結果のUNIONが私のために働くでしょう。複数のデータベースでSQLクエリを並列に実行し、ADO.NET Entity Frameworkを使用して結合結果を返す方法
私の最初の考えは、これらの5つのDBすべてにweb.configファイルと自分のコードで保存し、それぞれの接続文字列を渡し、接続文字列をparamとしてインスタンス化してからBackGroundWorkerを使用して接続文字列ごとに1つのスレッドをスピンオフし、すべてのDBに対して同じクエリを並列に実行します。各スレッドで1回実行し、最後にすべてのスレッドの結果セットを結合します。
これはうまくいくはずですが、これを解決するより良い方法があるのか、EFにスレッドで並列実行することでこれを行うことができるinbuiltメソッドがあるのだろうかと思います。
UPDATE
/// <summary>
/// Executes a store query in parallel on all the DB servers
/// </summary>
/// <typeparam name="TElement"></typeparam>
/// <param name="commandText"></param>
/// <returns></returns>
public List<TElement> ExecuteStoreQuery<TElement>(string commandText)
{
List<TElement> result = new List<TElement>();
// Create a blocking collection to store the execution results from each task
// A blocking collection is a thread safe collection that can be updated by multiple tasks
BlockingCollection<ObjectResult<TElement>> bc = new BlockingCollection<ObjectResult<TElement>>();
// Create a Task to run in paralled for each connection string
List<Task> tasks = new List<Task>();
foreach (string connString in this.connectionStrings)
{
Task task = Task.Factory.StartNew(() =>
{
// Create a new Connection
MyEntities entity = new MyEntities(connString);
this.contexts.Add(entity);
// Execute the query
var results = entity.ExecuteStoreQuery<TElement>(commandText);
// Add the results to the collection
if (results != null)
{
bc.Add(results);
}
});
tasks.Add(task);
}
// Wait till all the tasks are done
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException ae)
{
ae.Handle((x) =>
{
if (x is UnauthorizedAccessException) // This exception is known and we can handle it
{
return true;
}
else
{
return false;
}
});
}
// Add each item in blocking list to our result set
foreach (var item in bc)
{
result.AddRange(item);
}
return result;
}
でも、私は別の質問を持っています。 DBへの接続が失敗した場合でも、メソッドが結果を返すようにしたい。 5台のサーバのうち、少なくとも1台のサーバに接続できれば、結果を返すことになり、5台のサーバすべてに接続できなかった場合にのみ、失敗/例外をスローします。
どうすればよいですか?
私はTPLを試しましたが、これは私が思いついたものです – user330612