web-dev-qa-db-ja.com

LINQは、別のリストの任意の名前(文字列)に一致するリストのアイテムを返します

2つのリストがあります。 1は製品のコレクションです。もう1つは、店内の製品のコレクションです。

名前が製品のいずれかの名前と一致する場合、すべてのshopProductsを返すことができる必要があります。

私はこれを持っていますが、うまくいかないようです。何か案は?

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

名前が他のリストにあるすべてのショップ製品を教えてください。

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

LINQ-to-Objectsの場合、listOfProductsに多くのアイテムが含まれている場合、必要なすべての名前を含むHashSet<T>を作成すると、mightパフォーマンスが向上します。それをクエリで使用します。 HashSet<T>は、O(1)任意のIEnumerable<T>のO(n)と比較したルックアップパフォーマンス)を持ちます。

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

LINQ-to-SQLの場合、プロバイダーがクエリを手動で調整する必要なく、生成されたSQLを自動的に最適化できることを期待していますか?.

66
LukeH

たとえば、結合を使用できます。

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

参加に関する完全なガイドは here です。

10
Jon Egerton

同じ名前の製品が等しいという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());
4
Matt Ellen

これを試してください

var products  = shopProducts.Where(m=> listOfProducts.Select(l=>l.Name).ToList().Contains(m=>m.Name));
2
Theun Arbeider
var products = shopProducts
        .Where(shopProduct =>
                listOfProducts.Any(p => shopProduct.Name == p.Name))
        .ToList();
2
mgronber