Frage

Ich bin Abrufen von Daten aus allen drei Tabellen gleichzeitig Netzwerk-Latenz zu vermeiden. die Daten-Abruf ist ziemlich schnell, aber wenn ich eine Schleife durch die Ergebnisse wird viel Zeit verwendet

Int32[] arr = { 1 };
var query = from a in arr
            select new
            {
              Basket = from b in ent.Basket
                       where b.SUPERBASKETID == parentId
                       select new
                       {
                           Basket = b,
                           ObjectTypeId = 0, 
                           firstObjectId = "-1",
                       },

              BasketImage = from b in ent.Image
                            where b.BASKETID == parentId
                            select new
                            {
                                Image = b,
                                ObjectTypeId = 1, 
                                CheckedOutBy = b.CHECKEDOUTBY,
                                firstObjectId = b.FIRSTOBJECTID,
                                ParentBasket = (from parentBasket in ent.Basket
                                                where parentBasket.ID == b.BASKETID
                                                select parentBasket).ToList()[0],
                            },

              BasketFile = from b in ent.BasketFile
                           where b.BASKETID == parentId
                           select new
                           {
                               BasketFile = b,
                               ObjectTypeId = 2, 
                               CheckedOutBy = b.CHECKEDOUTBY,
                               firstObjectId = b.FIRSTOBJECTID,
                               ParentBasket = (from parentBasket in ent.Basket
                                               where parentBasket.ID == b.BASKETID
                                               select parentBasket),
                           }
            };

//Exception handling

var mixedElements = query.First();
ICollection<BasketItem> basketItems = new Collection<BasketItem>();

//Here 15 millis has been used
//only 6 elements were found

if (mixedElements.Basket.Count() > 0)
{
  foreach (var mixedBasket in mixedElements.Basket){}
}

if (mixedElements.BasketFile.Count() > 0)
{
  foreach (var mixedBasketFile in mixedElements.BasketFile){}
}

if (mixedElements.BasketImage.Count() > 0)
{
  foreach (var mixedBasketImage in mixedElements.BasketImage){}
}

//the empty loops takes 811 millis!!
War es hilfreich?

Lösung

Warum stören Sie die Zählungen vor den foreach-Anweisungen zu überprüfen? Wenn es keine Ergebnisse gibt, wird die foreach nur sofort beenden.

Ihre Anfragen sind eigentlich alle latenten werden - werden sie als ausgeführt werden, und wenn Sie für die Daten fragen. Vergessen Sie nicht, dass Ihre äußerste Abfrage ein LINQ to Objects-Abfrage ist. es zurückkehrt gerade das Ergebnis des Aufrufs ent.Basket.Where(...).Select(...) etc ... das ist eigentlich nicht die Abfrage ausführen

Ihr Plan alle drei Abfragen in einem Rutsch zu tun, ist nicht wirklich funktioniert. Indem jedoch separat für die Zählung zu fragen, können Sie tatsächlich jede Datenbankabfrage zweimal werden die Ausführung -. Nur ein einziges Mal die Zählung bekommen und einmal für die Ergebnisse

Ich empfehle, dass Sie in diesem Code der „Optimierungen“ loszuwerden, die es viel komplizierter und langsamer machen als nur den einfachsten Code schreiben Sie können.

Ich weiß nicht, von irgendeiner Weise LINQ to SQL zu bekommen (oder LINQ to EF) mehrere Abfragen in einem einzigen Aufruf auszuführen -. Aber dieser Ansatz sicherlich wird es nicht tun würde

Eine weitere kleine Andeutung, die in diesem Fall irrelevant ist, kann aber in LINQ to Objects nützlich sein - wenn Sie wollen herausfinden, ob es in einer Sammlung alle Daten ist, benutzen Sie einfach Any() statt Count() > 0 - auf diese Weise als stoppen sobald er etwas gefunden hat.

Andere Tipps

Sie verwenden IEnumerable in der foreach-Schleife. Implementationen haben nur Daten zu erstellen, wenn es gefragt wird. Ich würde auf diese Weise deuten darauf hin, dass der obige Code Ihre Daten lazily zugreift - das heißt, nur wenn Sie die Begriffe aufzuzählen

(was eigentlich passiert, wenn man Count() nennen.)

Setzen Sie einen System.Diagnostics.Stopwatch um den Anruf zu Count() und zu sehen, ob das den Großteil der Zeit ist, nehmen Sie sehen.

Ich kann hier nicht weiter kommentieren, weil Sie nicht die Art von ent in Ihrem Codebeispiel angeben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top