【问题标题】:LINQ CONTAINS IN C#LINQ 包含在 C# 中
【发布时间】:2014-05-17 18:46:43
【问题描述】:

我有一个如下所示的 linq 查询。当allStudents 包含大量数据时,它非常慢。我从不同的博客知道Contains 非常慢。谁能给我一个更好的解决方案来提高性能。

var selectedStudents = allStudents.Where(s => !studentsIdList.Contains(s.Id));

这里 allStudents 是一个 IQueryable 并且 studentIdList 是一个列表

【问题讨论】:

  • 表中有多少行,studentidlist 有多大,获得了多少命中?
  • Contains 本身并不慢。这取决于您使用的集合类型。例如,List<T> 上的Contains 可能需要与列表中元素数量成正比的时间,而使用HashSet<T>,将需要很少且几乎恒定的时间,无论如何集合中有多少个元素。
  • 大约 20k 行,studentIdlist 大约 15k
  • selectedStudents的类型和来源是什么?它是否与数据库相关?
  • - 不提供详细信息,如果您提供详细信息,将提供 +

标签: c# linq entity-framework contains


【解决方案1】:

这是 LINQ 中使用外连接并排除“空”值为 0 的所有结果的可能解决方案。假设没有学生的 ID 为零。对于更复杂的情况,您应该使用p == null。如果您的源是使用 EF 访问的数据库,则将使用数据库。

List<int> allStudents = new List<int> {1,2,3,4,5,6,7,8,9};
List <int> studentsIdList = new List<int> {1,3,5,7,9};

var q = 
        from c in allStudents 
        join p in studentsIdList on c equals p into ps 
        from p in ps.DefaultIfEmpty() 
        where p == 0
        select new { Student = c}; 

给出结果 2 4 6 8

【讨论】:

  • 你优雅的解决方案很诱人,但我仍然希望有人使用诊断计时器用大数据测试这里提出的解决方案
  • 在 SQL 术语中,这是一个标准的左连接,使用 null 来过滤掉“缺失”的项目。这是对数据库的一次调用,因此没有理由认为它会很慢。另一种选择是将其编写为 SQL 视图,然后直接调用它。
【解决方案2】:

您是否尝试在一个查询中获得所有学生

然后 allstudent 被排除在另一个查询中,然后迭代第一个查询,删除不需要的并比较时间并告诉我们:p

var allStudent = allStudents;
Var unwanted = allstudent.Where( s=> studentIdList == s.id);

然后

foreach( var item in unwanted ){
allStudent.remove( item);}

请告诉我们时差

【讨论】:

  • 这样会更慢
【解决方案3】:

当您处理大量数据并且想要获得良好性能时,请从数据库存储过程中获取,因为 linq 将在内存中处理,因此需要更多时间。

【讨论】:

  • 除非是 LINQ to SQL,当然也可以是 LINQ to Entities,否则 OP 不清楚。
【解决方案4】:

您似乎首先将所有学生从某个地方(可能是一个数据库?)拉出来,然后尝试将它们过滤掉,这是一个坏主意。相反,您应该让数据库来完成这项工作。

【讨论】:

  • 那么他应该使用存储过程吗?
  • @stackunderflow 不,他应该使用 LINQ to SQL 或 LINQ to Entities 之类的东西,这样他就可以将查询发送到数据库并只获取他需要的项目,而不是先获取所有项目然后 然后在本地过滤它们。
  • 如何使用这个。请推荐我@Safak Gur
  • @Azim:allStudentsstudentsIdList有哪些类型?我假设它们都是本地收藏。您应该更改填充这些集合的方式。您从数据库中获取项目,对吗?通过发送带有过滤器的查询,仅获取您需要的那些。你如何访问数据库?您是否手动发送查询字符串?你使用 ORM 框架吗?
  • @Azim:太好了,studentsIdList 是从哪里来的?你也从数据库中得到它吗?您应该编辑您的问题并提及详细信息(例如您正在使用实体框架来获取数据)。如何获得allStudentsstudentsIdList?如果您更新您的问题并从您使用实体上下文请求数据的那一点开始提供代码,我们可以为您提供更好的帮助。您还应该在您的问题中添加entity-framework 标签。
猜你喜欢
  • 1970-01-01
  • 2016-06-22
  • 2014-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 2016-02-05
相关资源
最近更新 更多