什么是“现代”的方式来找到两个列表对象中的常见项目?

我有两个包含不同类型的通用列表,例如,我们称之为ProductsEmployees 。 我正在尝试找到与Employees位于同一位置的product.SiteId == emp.SiteId ,即product.SiteId == emp.SiteId

 List lstProds; List lstEmps; 

我的(老skool)大脑告诉我使用forEach循环找到匹配但我怀疑有一个(’更好’/更快/更快?)的方式来使用Linq。 任何人都可以照亮我吗? 我在网上找到的所有例子都涉及原语列表(字符串/整数),并没有特别的帮助。

我会说:

 var products = from product in lstProds join employee in lstEmps on product.SiteId equals employee.SiteId select product; 

但是,如果有多个员工具有相同的站点ID,您将多次获得产品。 您可以使用Distinct来解决此问题,或者构建一组站点ID:

 var siteIds = new HashSet(lstEmps.Select(emp => emp.SiteId)); var products = lstProds.Where(product => siteIds.Contains(product.SiteId)); 

假设SiteId是一个int – 如果它是一个匿名类型或类似的东西,你可能需要一个额外的扩展方法:

 public static HashSet ToHashSet(this IEnumerable source) { return new HashSet(source); } 

然后:

 var siteIds = lstEmps.Select(emp => emp.SiteId).ToHashSet(); var products = lstProds.Where(product => siteIds.Contains(product.SiteId)); 

或者,如果您的员工很少,这将有效但速度相对较慢:

 var products = lstProds.Where(p => lstEmps.Any(emp => p.SiteId == emp.SiteId)); 

添加ToList调用以获取List而不是IEnumerable