出于数据库性能的原因,我应该实现LINQ查询吗?

出于数据库性能的原因,我应该实现LINQ查询吗?,linq,Linq,我有以下代码: var result = Database.Set<Product>() .Where(x => x.Product.CreatedAt >= fromDate && x.Product.CreatedAt <= toDate); var group1 = result .GroupBy(x => new { Id = x.Id, Name = x.Name }) .Selec

我有以下代码:

var result = Database.Set<Product>()
    .Where(x => x.Product.CreatedAt >= fromDate
             && x.Product.CreatedAt <= toDate);

var group1 = result
    .GroupBy(x => new { Id = x.Id, Name = x.Name })
    .Select(x => new { Id = x.Key.Id, Name = x.Key.Name });
var group2 = result
    .GroupBy(x => new { Id = x.Id, Price = x.Price })
    .Select(x => new { Id = x.Key.Id, Name = x.Key.Price });
var group3 = result
    .GroupBy(x => new { Id = x.Id, Category = x.Category })
    .Select(x => new { Id = x.Key.Id, Name = x.Key.Category });
var result=Database.Set()
。其中(x=>x.Product.CreatedAt>=fromDate
&&x.Product.CreatedAt new{Id=x.Id,Name=x.Name})
.Select(x=>new{Id=x.Key.Id,Name=x.Key.Name});
var group2=结果
.GroupBy(x=>new{Id=x.Id,Price=x.Price})
.Select(x=>new{Id=x.Key.Id,Name=x.Key.Price});
var group3=结果
.GroupBy(x=>new{Id=x.Id,Category=x.Category})
.Select(x=>new{Id=x.Key.Id,Name=x.Key.Category});
请不要注意GroupBy条件。让我们假设我需要这三组中的数据,以便进行进一步的处理

我假设上面的代码可能会触发至少三个SQL查询来生成结果。这样做是否不正确

var result = Database.Set<Product>()
    .Where(x => x.Product.CreatedAt >= fromDate
             && x.Product.CreatedAt <= toDate)
    .ToList();
var result=Database.Set()
。其中(x=>x.Product.CreatedAt>=fromDate

&&x.Product.CreatedAt回答你的问题:是的。你的推理是正确的。好的一面是你击中数据库一次,而不是4次。坏的一面取决于你拥有的数据量。对于相对较小的结果集,确实没有坏的一面


但是,正如Adam对您的问题所作的评论,您确实应该尝试两种方法,并使用
秒表
类来分析它们。

您的推理是正确的,调用ToList()将只使用一个SQL查询将数据拉入本地内存,然后后续的group和select操作将仅在本地内存中执行

由于后续的Linq查询只是对数据进行重新排序,因此将其传递到SQL server并以不同的顺序多次下载数据不会带来太多好处。主要的好处是减少了客户端上的内存占用。如果数据太大,无法安装在本地计算机上,则必须执行以下操作:在SQL server上分组并将其逐段拉到客户端

如果后续Linq查询进一步过滤数据,而不是仅仅重新排序,那么在第一个查询上使用.ToList的决定就不那么明确了。第一个查询可能会拉下比您需要的多得多的数据,这可能比进行三个查询(每个查询只拉下一点数据)的成本更高


另一个有利于在一个查询中提取数据并在本地内存中重新排序的因素是三个最终结果集之间的数据一致性。如果运行3个SQL查询,由于服务器上同时发生更新,每个查询中可能会得到不同的结果。通过将数据向下提取一次,您可以对数据进行快照,从而将其与数据库隔离同时更新,这保证了三个分组包含完全相同的数据,只是顺序不同。

作为补充说明,您的匿名对象创建可以缩短:例如,
new{x.Id,x.Category}
。您的推理对我来说是正确的。使用秒表类来确定两种方式的时间,然后使用它运行。