Ich möchte eine Auflistung von db connect-Zeichenfolgen durchlaufen und eine Abfrage für alle DBs ausführen, dann jedes IEnumberable-Ergebnis in einer IEnumerable-Liste kombinieren. Die synchrone Version sieht wie folgt aus:Variable Nummer von LINQ-Abfragen asynchron ausführen
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();
}
}
Diese Frage kann mehrere Unterfragen, da es fühlt sich an wie ich mit ein paar verschiedene Dinge bin zu kämpfen: (1) Wie soll getSitesForInstance() geschrieben werden? Sollte es sein
private async Task<List<SiteInfoModel>> getSitesForInstance()
Wenn es async sein sollte, dann wie schreibe ich den linq Ausdruck. Ich habe versucht, IEnumerable in IQueryable und mit .ToListAsync() zu ändern, aber ich bekomme einen Fehler bei der Projektion eines nicht-anonymen Typs. Kann es ohne asynchrone Task geschrieben werden und die Abfrage trotzdem gleichzeitig über alle Verbindungszeichenfolgen ausgeführt werden? Wenn es so oder so gemacht werden kann, ist es besser oder schlechter.
Der andere Teil der Frage ist (2) wie sollte ListSites() aussehen, wenn geschrieben, um gleichzeitige DB-Aufrufe zu machen? Ich habe mir this example angesehen, aber es bringt mich nicht wirklich zu einer funktionierenden Lösung. Ich habe mit so etwas herumgespielt:
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);
... aber das konnte nicht funktionieren. Jeder DB-Aufruf gibt eine Liste zurück. Wenn die Ergebnisse aller Aufgaben in der Variablen lstSites kombiniert werden - was das Ansichtsmodell ist - dann wird das Problem/die Frage gelöst/beantwortet.
Nicht sicher, warum Leute stimmen zu schließen - aber ich bin mir auch nicht sicher, warum es nicht funktionieren würde. Was genau hat mit deiner Async-Version nicht funktioniert? Ich mache etwas ähnliches in einer Anwendung, die gut funktioniert. –