C# Linq用于通过比较两个属性值从列表1中选择列表2中存在的元素

C# Linq用于通过比较两个属性值从列表1中选择列表2中存在的元素,c#,linq,filter,C#,Linq,Filter,如何从两个不同的列表中提取找到以下表达式的所有元素 List1.id = List2.id && List1.CategoryId = list2.CategoryId 以及如何通过提取主列表中缺少的元素来进行反转 !(List1.id = List2.id && List1.CategoryId = list2.CategoryId) 您可以为您的数据类型和用途实现一个简单的IComparer var intersection = List1.Inters

如何从两个不同的列表中提取找到以下表达式的所有元素

List1.id = List2.id && List1.CategoryId = list2.CategoryId
以及如何通过提取主列表中缺少的元素来进行反转

!(List1.id = List2.id && List1.CategoryId = list2.CategoryId)

您可以为您的数据类型和用途实现一个简单的
IComparer

 var intersection = List1.Intersect(List2, myCategoryIdComparer);

 var notRepeating = List1.Union(List2).Except(intersection);

 var notInList1 = List2.Except(List1, myCategoryIdComparer);
您可以轻松实现
IComparer

 public class CategoryComparer : IComparer  { 
          int IComparerList1.CompareIntersect( Object x, Object y )  {
          // do some type checks to make sure both are CategoryObject
          return ((CategoryObject)x).CategoryID
              .Compare(((CategoryObject)y).CategoryIdmyCategoryIdComparer);
      } 
  }

您还可以使用
join
子句,尽管它需要您初始化许多匿名类型

var result = (from l1 in list1
              join l2 in list2 on new {l1.Id, l1.Category} 
              equals new {l2.Id, l2.Category}
              select l1).ToArray();

因此,第一种情况是基本的
Join
操作,Linq支持:

var matchingItems = from item1 in list1
            join item2 in list2
            on new{ item1.id, item1.CategoryId} 
            equals new{ item2.id, item2.CategoryId}
            select new { item1, item2 };
对于第二种情况:

var idValues = list2.Select(item => new { item.id, item.CategoryId })
    .ToHashSet();
var missingItems = list1.Where(item => !idValues.Contains(new { item.id, item.CategoryId }));
以下是
ToHashSet
的定义:

public static class Extensions
{
    public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source)
    {
        return new HashSet<T>(source);
    }
}
公共静态类扩展
{
公共静态HashSet到HashSet(此IEnumerable源)
{
返回新的哈希集(源);
}
}

这将无法处理第二种情况您尝试第二种情况是不对的。您需要获得成对的项,以便每对项都具有不同的ID值。这是通过
SelectMany
完成的(在第一次查询所选对之前,您也无法使用
对其进行拟合,除了
)。哦,还不清楚它是否适用,但是
Intersect
仅在两个列表类型相同的情况下有效,即使使用自定义比较器也是如此。您不能使用它连接两个具有不同编译时类型的列表。@请注意,问题中没有指定类型。如果这两种类型都有CategoryID,IComparer可以比较暴露其类别和ID属性的接口。这就是为什么我说,“不清楚它是否适用”。这可能是一个问题,也可能不是。如果你用
Join
来代替,这是一个完全可以忽略的问题,因为从概念上讲,这就是内部连接的定义。这将无法处理第二种情况。这里的问题是,你可以写多少行来做同样的简单事情?我不明白你的意思。你是说你可以用更少的代码做同样的事情吗?如果是这样的话,一定要证明。目前你的第一个答案是不完整的,如果你完成了会比这个长很多,而你的第二个答案就是不起作用,所以比较它们是无效的。你的答案就是我想要的,因为我提到的那些列表在这种特殊情况下不是同一类型的,但在你的最后一个例子中,我得到了两个表上都存在的项目列表。基于这个返回的列表,我可以实现一个过滤器来获取列表2中缺少的项目的返回列表吗?