enter code here
В моем веб-приложении у меня есть 5 экземпляров базы данных с одинаковыми схемами таблиц на разных серверах SQL.Я хочу выполнить SQL-запрос (или запросы) с помощью метода ExecuteStoreQuery (), доступного в Objectcontext, ко всем этим 5 базам данных / серверам параллельно и вернуть объединенные результаты.Меня не волнуют дубликаты, поэтому UNION всех результатов всех БД будет работать для меня.
Сначала я хотел сохранить строки подключения ко всем этим 5 БД в моем файле web.config и в моемкод, просмотрите каждую строку подключения и создайте экземпляр объекта Enitites со строкой подключения в качестве параметра, а затем используйте BackGroundWorker, чтобы выделить один поток на строку подключения и выполнить один и тот же запрос для всех БД параллельно, по одному выполнению в каждом потоке, а затем объединитьнаборы результатов из всех потоков в конце.
Это должно работать, но мне интересно, есть ли лучший способ решить эту проблему и есть ли в EF какие-либо встроенные методы, которые позволяют мне делать это без менявозиться с параллельным выполнением через потоки.
Есть идеи?
ОБНОВЛЕНИЕ
/// <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;
}
У меня есть еще один вопрос.Я хочу, чтобы мой метод возвращал результаты, даже если некоторые из соединений с БД перестали работать.Таким образом, из 5 серверов, если я могу подключиться по крайней мере к 1 серверу, то я хочу вернуть результаты и выдать ошибку / исключение, только если мне не удалось подключиться ко всем 5 серверам.
Какя делаю это?