Count() внутри запроса linq, как избежать проблем с производительностью?

#linq

#linq

Вопрос:

У меня есть это заявление linq, и я сталкиваюсь с некоторыми серьезными проблемами с производительностью. Я считаю, что проблема заключается в моем.Вызовы Count() в середине кода.

 var products = from product in pm_products
                       join price in GetResellers().Where(x => x.Price != 0) on product.Id equals price.PM_Price.Product_Id into productPrices
                       let minprice = productPrices.Min(x => x.Price)
                       let maxprice = productPrices.Max(x => x.Price)
                       let difference = ((double)maxprice - (double)minprice)/(double)minprice * 100
                       let number = productPrices.Count()
                       let success = productPrices.Where(x => x.Status == PriceStatus.OKAY).Count()
                       let unknown = productPrices.Where(x => x.Status == PriceStatus.NONE).Count()
                       let fail = productPrices.Where(x => x.Status == PriceStatus.FAIL).Count()
                       select new Product
                       {
                           PM_Product = product,
                           BestPrice = minprice,
                           WorstPrice = maxprice,
                           Fail = fail,
                           Number = number,
                           Success = success,
                           Unknown = unknown,
                           Difference = difference
                       };
 

Я читал, что Count() выполняет запрос, но я хочу, чтобы он выполнялся только один раз. Как я могу добиться этого на основе моей конструкции выше?

Комментарии:

1. Что произойдет, если вы удалите Count() ? Ваш запрос становится намного быстрее?

2. Ну, вы уже агрегируете productPrices соединение по крайней мере еще два раза (min и max), поэтому я сомневаюсь, что за это отвечает только Count.

3. ДА. Он длится от 1600 мс до 32 мс

4. @Peter Вы пробовали перенести свое условие из Where предложения внутрь Count вызова? То есть удалите Where и сделайте productPrices.Count(x => x.Status == PriceStatus.OKAY) . Это что-нибудь улучшает?

5. @Asad Я сделал то, что вы предложили, но, к сожалению, время выполнения не изменилось

Ответ №1:

Вы можете принести базовую коллекцию, а затем сделать это в памяти, и, возможно, это поможет повысить производительность. Что-то вроде этого:

 let prodPrices = productPrices.Select(pp=>new {pp.Id, pp.Status})
 

затем включите его в свой финал select , и вы сможете получить подсчеты из этого в памяти