Question

Je récupère les données des 3 tables en même temps pour éviter la latence du réseau. La récupération des données est assez rapide, mais lorsque je parcours les résultats, cela prend beaucoup de temps

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!!
Était-ce utile?

La solution

Pourquoi prenez-vous la peine de vérifier les comptes avant les déclarations Foreach? S'il n'y a pas de résultat, le foreach finira juste immédiatement.

Vos requêtes sont en fait toutes différées - elles seront exécutées au fur et à mesure que vous demanderez les données. N'oubliez pas que votre requête la plus externe est une requête LINQ to Objects: elle ne fait que renvoyer le résultat de l'appel de ent.Basket.Where (...). Sélectionnez (...) etc ... qui n'exécute pas réellement la requête.

Votre plan pour traiter les trois requêtes en une fois ne fonctionne pas. Cependant, en demandant le nombre séparément, vous exécuterez peut-être chaque requête de base de données deux fois, une fois pour obtenir le nombre et une fois pour les résultats.

Je vous suggère fortement de vous débarrasser des "optimisations". dans ce code, ce qui le rend beaucoup plus compliqué et plus lent que d'écrire simplement le code le plus simple possible.

Je ne connais aucun moyen d'obtenir que LINQ to SQL (ou LINQ to EF) exécute plusieurs requêtes en un seul appel - mais cette approche ne le fera certainement pas.

Un autre indice mineur qui n'est pas pertinent dans ce cas, mais qui peut être utile dans LINQ to Objects - si vous voulez savoir s'il existe des données dans une collection, utilisez simplement Any () . de Compter () > 0 - de cette façon, il peut s'arrêter dès qu'il trouve quoi que ce soit.

Autres conseils

Vous utilisez IEnumerable dans la boucle foreach. Les implémentations doivent seulement préparer les données à la demande. De cette façon, je suggérerais que le code ci-dessus accède paresseusement à vos données, c'est-à-dire uniquement lorsque vous énumérez les éléments (ce qui se produit lorsque vous appelez Count () .)

Placez un System.Diagnostics.Stopwatch autour de l'appel à Count () et voyez si cela prend la majeure partie du temps que vous voyez.

Je ne peux pas commenter davantage ici car vous ne spécifiez pas le type de ent dans votre exemple de code.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top