简体   繁体   English

LINQ查询:根据键确定一个列表中的对象是否存在于另一个列表中

[英]LINQ Query: Determining if object in one list exists in another based on key

Basically what I'm trying to do is take a list of objects and filter it based on a number of criteria where one of the criteria is that the key doesn't exist in another list. 基本上我要做的是获取一个对象列表并根据一些标准对其进行过滤,其中一个标准是该键在另一个列表中不存在。 Here's an example: 这是一个例子:
My two classes are similar to this: 我的两个类与此类似:

public class Test  
{  
  public string name;  
  public string instructor_name;  
  public string course;  
}  

public class Appointment  
{  
  public string site;
  public DateTime forWhen;
  public string testName;
}

I want to sort through a List<Test> by looking at the course and making sure that test doesn't exist in the List<Appointment>. 我想通过查看课程并确保List <Appointment>中不存在测试来对List <Test>进行排序。 In SQL I'd do it something like this: 在SQL中我会这样做:

SELECT new Group<Test>(c.Key, c)
FROM tests in testList
WHERE tests.Course != "Science"
AND tests.name NOT IN (SELECT testName FROM appotList)

However, I can't figure out how I would do this in LINQ. 但是,我无法弄清楚如何在LINQ中执行此操作。 Any ideas? 有任何想法吗?

If you're talking about performing client-side filtering, that's pretty easy with LINQ to Objects. 如果您正在谈论执行客户端过滤,那么使用LINQ to Objects非常容易。 Something like this: 像这样的东西:

List<Test> tests = ...;
List<Appointment> appts = ...;

var query = tests.Except(
            tests.Join(appts, t => t.name, a => a.testName, (t, a) => t));

The following is slightly simpler to read: 以下内容略微简单易读:

var query = tests.Where(t => !appts.Any(a => a.testName == t.name));

But the first version will be faster, since the Join function will compute a hash table of the matches rather than doing a linear search of the appts list for every element in tests . 但是第一个版本会更快,因为Join函数将计算匹配的哈希表,而不是对tests每个元素进行appts列表的线性搜索。

http://introducinglinq.com/blogs/marcorusso/archive/2008/01/14/the-not-in-clause-in-linq-to-sql.aspx http://introducinglinq.com/blogs/marcorusso/archive/2008/01/14/the-not-in-clause-in-linq-to-sql.aspx

Consider this code that returns all the customers who don't have an order in the Orders table. 请考虑此代码,该代码返回Orders表中没有订单的所有客户。 This is one SQL query that returns that value. 这是一个返回该值的SQL查询。

SELECT *
FROM [dbo].[Customers] AS [t0]
WHERE [t0].[CustomerID] NOT IN (
    SELECT [t1].[CustomerID]
    FROM [dbo].[Orders] AS [t1]
)

This is not the faster way to get the desired result (using a NOT EXISTS is the favorite way - more on this shortly). 这不是获得所需结果的更快方式(使用NOT EXISTS是最喜欢的方式 - 更多关于这一点)。 LINQ offers a Contains extension method that allows writing the following code. LINQ提供了一个包含扩展方法,允许编写以下代码。

NorthwindDataContext dc = new NorthwindDataContext();
dc.Log = Console.Out;
var query =
    from c in dc.Customers
    where !(from o in dc.Orders
            select o.CustomerID)
           .Contains(c.CustomerID)
    select c;
foreach (var c in query) Console.WriteLine( c );

In LINQ to SQL the query is translated into this SQL code: 在LINQ to SQL中,查询被转换为此SQL代码:

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName],
       [t0].[ContactTitle], [t0].[Address], [t0].[City],
       [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0]
WHERE NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM [dbo].[Orders] AS [t1]
    WHERE [t1].[CustomerID] = [t0].[CustomerID]
    ))

This approach is not only semantically equivalent, but also faster in execution. 这种方法不仅在语义上等同,而且执行速度更快。 The following is the result with SET STATISTICS IO ON. 以下是SET STATISTICS IO ON的结果。 The first result is for the hand-written query that use the NOT IN clause. 第一个结果是使用NOT IN子句的手写查询。 The second result is for the LINQ to SQL generated query. 第二个结果是LINQ to SQL生成的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 linq查询从一个列表中选择另一个列表 - linq query for selecting from one list based on another c#Linq-检查组合键是否在另一个列表中 - c# Linq - Check if composite key exists in another list Linq根据另一个列表的成员资格从一个列表中排除自定义对象(C#) - Linq to exclude a custom object from one List based on membership of another List (c#) 如何根据另一个列表中一个属性的所有值过滤linq查询 - How to filter linq query based on all of the values of one property from another list 使用Linq进行反对,我如何才能基于同一列表中的另一个字段来获取一个字段的值 - Using Linq to object, how can I get one field's value based on another in the same list Linq通过另一个列表中外键的出现查询订单列表 - Linq query to order list by occurences of foreign key in another list Linq根据另一个列表查询对象列表的结果 - Linq to query results of list of objects based on another list 在一个查询中基于Linq中的外部列表过滤给定列表 - Filter a given List based on external List in Linq in one query LINQ查询-从另一个列表中排除一个列表的值 - LINQ Query - exclude the values of one list from another list Linq查询我的列表 <Square> 查看一个列表中的项目是否在另一个列表中 - Linq query for my List<Square> to see if an item of one list is in another
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM