Pergunta

Eu estou buscando dados de todas as 3 mesas de uma vez para a latência da rede evitar. Buscar os dados é bastante rápido, mas quando eu percorrer os resultados muito tempo é usado

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!!
Foi útil?

Solução

Por que você está incomodando a verificar as contagens antes das demonstrações foreach? Se não houver resultados, o foreach só vai terminar imediatamente.

As suas consultas são realmente tudo o que está sendo adiada - que vai ser executado como e quando você perguntar para os dados. Não se esqueça de que sua consulta externa é uma consulta LINQ to Objects:. É só devolver o resultado da chamada ent.Basket.Where(...).Select(...) etc ... que na verdade não executar a consulta

Seu plano para fazer todas as três consultas de uma só vez não está realmente trabalhando. No entanto, por pedir a contagem separadamente, você pode realmente ser a execução de cada consulta de banco de dados duas vezes -. Uma vez apenas começando a contagem e uma vez para os resultados

Eu sugiro fortemente que você se livrar dos "otimizações" neste código que são tornando-se muito mais complicado e mais lento do que apenas escrever o código mais simples possível.

Eu não sei de nenhuma maneira de obter LINQ to SQL (ou LINQ para EF) para executar várias consultas em uma única chamada -. Mas esta abordagem não é certamente vai fazê-lo

Uma outra dica menor, que é irrelevante neste caso, mas pode ser útil em LINQ to Objects - se você quiser descobrir se há quaisquer dados em uma coleção, basta usar Any() vez de Count() > 0 - de que maneira ele pode parar como logo que ele é encontrado nada.

Outras dicas

Você está usando IEnumerable no loop foreach. Implementações só tem que preparar os dados quando é solicitado. Desta forma, sugiro que o código acima está acessando seus dados preguiçosamente - (. Que realmente acontece quando você chamar Count()) isto é, somente quando você enumerar os itens

Coloque um System.Diagnostics.Stopwatch em torno da chamada para Count() e ver se que está tomando a maior parte do tempo que você está vendo.

Eu não posso comentar mais aqui porque você não especificar o tipo de ent em sua amostra de código.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top