在 LINQ 中使用组时如何提高性能

Posted

技术标签:

【中文标题】在 LINQ 中使用组时如何提高性能【英文标题】:How to increate the performance when using group in LINQ 【发布时间】:2021-11-01 10:02:06 【问题描述】:

数据库

Cars       | CarDetails         | Owners
----------------------------------
Id         | CarDetailId        | Id
Name       | CarId              | CarId
Type       | CarId              | OwnerName
           |                    | PhoneNumber

LINQ 代码

var intiQuery = from c in Cars
              join cd in CarDetails
              join o in Owners
              select new  c,cd,o

var results = from qry in intiQuery 
                           group new  qry.c, qry.cd, qry.o by qry.c.Id into g
                           select new
              select new  CarId= g.Key,
                           Name = g.Select(g=>g.c.Name).FirstOrDefault(),
                           Type = g.Select(g=>g.c.Type).FirstOrDefault(),
                           Price= g.Select(g=>g.cd.Price).FirstOrDefault(),
                           OwnerName= g.Select(g=>g.o.OwnerName).FirstOrDefault(),
                           PhoneNumber= g.Select(g=>g.o.PhoneNumber).FirstOrDefault(),
                         

我的问题只是在调用此查询时如何提高性能,正如您对每个字段所见,我需要 .Select().FirstOrDefault() 来获取相应的数据。如果假设我有 100 个数据,我将需要一个一个地获取数据 500 次,显示数据需要很长时间。

额外信息,以防有人不清楚。

Cars
Id    |Name            |Type
-----------------------------------
1     |Toyota          |Family

CarDetails
CarDetailId | CarId       | Price
-----------------------------------
1           | 1           | 200000

Owners
Id| CarId       | OwnerName   | PhoneNumber
-----------------------------------
1 | 1           | Mitch       | 48774800
2 | 1           | Camilo      | 87404078

我想要得到的结果是这样的希望你们中的一些人能有一个更清晰的画面

CarId| Name   | Type   | Price  |OwnerName        |PhoneNumber 
----------------------------------------------------------------------
1    | Toyota | Family | 200000 | Mitch,Camilo    | 48774800,87404078

【问题讨论】:

为什么使用交叉连接而不是简单的内/左连接?该查询没有任何意义,因为它是当前编写的。实际上,我什至不确定是否可以编译 @MitchWheat@CamiloTerevinto 请再读一读我的问题,更新 Ty。 【参考方案1】:

这绝对不是最好的解决方案,但它肯定很容易理解,如果您不过滤数据,那么它可能就足够了。

正如您所说,性能问题是因为您对数据库进行了数百次访问,因此我们可以通过三个简单的查询从数据库中提取信息来轻松避免这种情况。

var allCars = Cars.ToList();
var allCarDetails = CarDetails.ToList();
var allOwners= Owners.ToList();

一旦您在内存中拥有所有这些信息,您就可以操作内存中的对象以产生您需要的结果。

var results = (from car in allCars
               let owners = allOwners.Where(a => a.CarID == car.Id)

 select new
 
     CarID = car.Id,
     car.Name,
     car.Type,
     Price = allCarDetails.Where(a => a.CarID == car.Id).Select(a => a.Price).SingleOrDefault(),

     OwnerName = String.Join(',', owners.Select(a => a.Name)),
     PhoneNumber = String.Join(',', owners.Select(a => a.PhoneNumber))
 
 );

如果您的表有很多您没有提到的额外字段,那么我们可能希望更改最初的三个查询以仅提取所需的信息。

【讨论】:

以上是关于在 LINQ 中使用组时如何提高性能的主要内容,如果未能解决你的问题,请参考以下文章

在 LINQ-To-SQL 中,我应该使用 NOLOCK 来提高性能吗?

在 Windows Phone 上使用 Linq to SQL 时,是不是可以提高批量删除的性能?

我可以在我的数据库和 EF 上使用 View 来提高只读性能吗?

如何提高 Sql server 中 Distinct Query 的性能

java中大量数据如何提高性能?

如何使用 HAML 提高 Sinatra 性能?