LINQ返回List中与其他列表中的任何名称(字符串)匹配的项目

时间:2011-03-28 08:47:36

标签: c# linq linq-to-sql linq-to-objects

我有2个清单。 1是产品的集合。另一个是商店里的产品系列。

如果名称与产品中的任何名称匹配,我需要能够返回所有shopProducts。

我有这个,但它似乎不起作用。有什么想法吗?

    var products = shopProducts.Where(p => p.Name.Any(listOfProducts.
             Select(l => l.Name).ToList())).ToList();

我需要说给我所有其他名单中存在名称的商店产品。

5 个答案:

答案 0 :(得分:66)

var products = shopProducts.Where(p => listOfProducts.Any(l => p.Name == l.Name))
                           .ToList();

对于LINQ到对象,如果listOfProducts包含许多项目,那么如果创建包含所有必需名称的HashSet<T>,那么可能会获得更好的性能,然后使用在您的查询中。对于任意HashSet<T>IEnumerable<T>与O(n)相比具有O(1)查找性能。

var names = new HashSet<string>(listOfProducts.Select(p => p.Name));
var products = shopProducts.Where(p => names.Contains(p.Name))
                           .ToList();

对于LINQ-to-SQL,我希望(希望?)提供者可以自动优化生成的SQL,而无需任何手动调整查询。

答案 1 :(得分:10)

您可以使用联接,例如:

var q = from sp in shopProducts
        join p in listOfProducts on sp.Name equals p.Name
        select sp;

关于加入的更全面的指南是here

答案 2 :(得分:4)

您可以创建IEqualityComparer<T>,表示名称相同的产品相同。

class ProductNameEqulity : IEqualityComparer<Product>
{
    public bool Equals(Product p1, Product p2)
    {
        return p1.Name == p2.Name
    }

    public int GetHashCode(Product product)
    {
        return product.Name.GetHashCode();
    }
}

然后您可以在Intersect扩展方法中使用它。

var products = shopProducts.Intersect(listOfProducts, new ProductNameEquality());

答案 3 :(得分:2)

请试试这个

var products  = shopProducts.Where(m=> listOfProducts.Select(l=>l.Name).ToList().Contains(m=>m.Name));

答案 4 :(得分:2)

var products = shopProducts
        .Where(shopProduct =>
                listOfProducts.Any(p => shopProduct.Name == p.Name))
        .ToList();