#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
, и вы сможете получить подсчеты из этого в памяти