C# LINQ查询即使在很小的集合上执行也非常慢

C# LINQ查询即使在很小的集合上执行也非常慢,c#,asp.net,asp.net-mvc,linq,c#-4.0,C#,Asp.net,Asp.net Mvc,Linq,C# 4.0,我有一个非常奇怪的问题,我的LINQ查询执行得非常慢。代码如下: var user = ctx.Users.FirstOrDefault(x => x.Username== username); ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new SalesViewModel { ImageURL = pr.Select(x=>x.ImageURL).FirstOrDefault(),

我有一个非常奇怪的问题,我的LINQ查询执行得非常慢。代码如下:

var user = ctx.Users.FirstOrDefault(x => x.Username== username);

ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new SalesViewModel
{
 ImageURL = pr.Select(x=>x.ImageURL).FirstOrDefault(),
 Title= pr.Select(x=>x.Title).FirstOrDefault(),
 Sales = pr.Select(x=>x.Transactions.Sum(y=>y.QuantitySold)).FirstOrDefault()
 })
 .OrderByDescending(x=>x.Sales)
 .ToList();
因此,用户对象包含一个ICollection集合项,其中包含1300个项。每个项目都包含另一个ICollection,称为事务集合

我注意到每个项目最多有20-25个事务,所以项目中的集合并没有那么大

我在这里做错了什么?为什么LINQ需要30-40秒来处理此代码


有什么方法可以让它更好吗???

请将您的linq查询更改为:

var user = ctx.Users.FirstOrDefault(x => x.Username== username);

ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new SalesViewModel
{
    ImageURL = pr.FirstOrDefault(x=>x.ImageURL),
    Title= pr.FirstOrDefault(x=>x.Title),
    Sales = pr.FirstOrDefault(x=>x.Transactions.Sum(y=>y.QuantitySold))
})
.OrderByDescending(x=>x.Sales)
.ToList();
尝试以下方法:

var ids = user.Items
    .GroupBy(x => x.ItemId)
    .Where(x=> x.Any())
    .Select(pr => pr.First().Id); /* No ToList yet */

user
    .Items
    .Where(x=> ids.Contains(x.Id)) // <--
    .Select(pr => new SalesViewModel
    {
        ImageURL = x.ImageURL,
        Title= x.Title,
        Sales = x.Transactions.Sum(y=>y.QuantitySold)
    })
    .ToList();

方法是,从昂贵的GroupBy读取主键,并将其用作主查询的子查询。在LINQPad或SSMS中尝试这一点,看看这是否会有所不同。

正如Ivan Stoev在评论中所写,这应该是由延迟加载引起的N+1查询问题。这里的答案是使用include语句并在对事务求和之前加载子实体

var user = ctx.Users.FirstOrDefault(x => x.Username== username).Include("Items").Include("Transactions");

如果ItemId是项目的主键,则不需要group bytable@octavioccl这并不不幸:。。。这是一个独立的属性,我从ctx猜测这是实体的linq?如果是这样,请使用探查器查看生成了哪些SQL语句。@stuartd是正确的,好的,我将看一看thx:听起来像是延迟加载导致的N+1查询问题。Muhammad,当您按ItemID分组时,如何实际访问ImageURL/TItle/Transactions属性?pr是一个组,如果只需要删除IEnumerable,则可以使它更快。ToList@MuhammadQasim表示无法将lambda表达式转换为预期的delegateYour答案使用的代码较少,但语义相同,因此不会修复原始代码中的任何问题。它说.select在当前上下文中不存在?@User987抱歉,我更新了答案,第一个查询现在有一个额外的Where和更新的select。出于某种原因,它仍然说select在当前上下文中不存在:D@User987伟大的让我知道进展如何。