I want to loop through a collection of db connect strings and execute a query against all DBs, then combine each IEnumerable
result into one IEnumerable List<T>
.
The synchronous version looks like this:
public ActionResult ListSites()
{
ConnectionStringSettingsCollection ConnectionStrings = ConfigurationManager.ConnectionStrings;
List<SiteInfoModel> lstSites = new List<SiteInfoModel>();
foreach (ConnectionStringSettings cn in ConnectionStrings)
{
lstSites.AddRange(getSitesForInstance(cn));
}
return View("~/Views/Sites/List.cshtml", lstSites);
}
private List<SiteInfoModel> getSitesForInstance(ConnectionStringSettings css)
{
using (STContext db = new STContext(css.ConnectionString))
{
IEnumerable<SiteTracker.Data.site_info> sites = db.Sites;
return (from s in sites
orderby s.name
select new SiteInfoModel
{
instance = css.Name,
siteName = formatValue(s.name, s.active),
siteUrl = formatValue(s.url, s.active),
siteId = s.site_id,
isActive = s.active
}).ToList();
}
}
This question may have several sub-questions since it feels like I'm struggling with a few different things:
How should
getSitesForInstance()
be written? Should it beprivate async Task<List<SiteInfoModel>> getSitesForInstance()
If it should be async, then how do I write the linq expression? I tried changing
IEnumerable
toIQueryable
and using.ToListAsync()
but I get an error about projecting a non-anonymous type. Can it be written withoutasync Task<T>
and still have the query execute concurrently across all connection strings? If it can be done either way, is one way better or worse.How should ListSites() look when written to make concurrent database calls? I've looked at this example but it doesn't quite get me to a working solution. I've played around with something like this:
Task<List<SiteInfoModel>>[] tasks = new Task<List<SiteInfoModel>>[ConnectionStrings.Count]; for (int i = 0; i < ConnectionStrings.Count - 1; i++) { tasks[i] = getSitesForInstance(ConnectionStrings[i]); } Task.WaitAll(tasks);
...but couldn't get that working. Each database call returns a
List<SiteInfoModel>
. When the results from all tasks are combined into the variable lstSites - which is the view model - then the problem/question is solved/answered.