2009-06-10 8 views
32

Ich habe auf Google gesucht, aber nichts zu finden, das den Trick für mich tut.LINQ Wo in der Sammlungsklausel

Wie Sie wissen, hat SQL eine Klausel "where x in (1,2,3)", mit der Sie mehrere Werte überprüfen können. Ich benutze linq, aber ich kann nicht scheinen, ein Stück der Syntax zu finden, die dasselbe wie die oben genannte Aussage tut.

Ich habe eine Sammlung von der Kategorie-ID (List), gegen den Ich mag würde

ich etwas überprüfen gefunden, die die .contains Methode verwendet, aber es baut nicht einmal.

Antwort

40

Sie müssen verwenden die Methode auf Ihrer ID-Liste enthält:

var query = from t in db.Table 
      where idList.Contains(t.Id) 
      select t; 
+0

Ich habe eine Follow-up obwohl. die Spalte der IDs ist Nullable (die ich vergessen und mit der Eigenschaft value behoben) Was passiert, wenn der Wert null ist? –

+1

Wenn der Wert von t.Id gleich null ist, enthält das Ergebnis diesen Datensatz nicht. –

3

Hier ist eine article, die den Ansatz darstellt. Sie sollten tatsächlich die Contains-Methode für Ihre Sammlung verwenden, die in die IN-Klausel übersetzt wird.

+5

Der nicht verlinkte Artikel Länger existiert. – MattD

18

Die Syntax ist unten:

IEnumerable<int> categoryIds = yourListOfIds; 

var categories = _dataContext.Categories.Where(c => categoryIds.Contains(c.CategoryId)); 

Das Wichtigste ist zu beachten, dass Sie tun, die auf Ihrer Liste enthält von IDs - nicht auf dem Objekt, das Sie in anwenden würden, wenn Sie sql schreiben würden.

1

Hier ist meine Realisierung, bei der() Methode, IQueryable Sammlung durch eine Reihe von ausgewählten Objekten zu filtern:

public static IQueryable<T> WhereIn<T,TProp>(this IQueryable<T> source, Expression<Func<T,TProp>> memberExpr, IEnumerable<TProp> values) where T : class 
    { 
     Expression predicate = null; 
     ParameterExpression param = Expression.Parameter(typeof(T), "t"); 

     bool IsFirst = true; 

     MemberExpression me = (MemberExpression) memberExpr.Body; 
     foreach (TProp val in values) 
     { 
      ConstantExpression ce = Expression.Constant(val); 


      Expression comparison = Expression.Equal(me, ce); 

      if (IsFirst) 
      { 
       predicate = comparison; 
       IsFirst = false; 
      } 
      else 
      { 
       predicate = Expression.Or(predicate, comparison); 
      } 
     } 

     return predicate != null 
      ? source.Where(Expression.Lambda<Func<T, bool>>(predicate, param)).AsQueryable<T>() 
      : source; 
    } 

und Berufung dieser Methode sieht so aus:

IQueryable<Product> q = context.Products.ToList(); 

var SelectedProducts = new List<Product> 
{ 
    new Product{Id=23}, 
    new Product{Id=56} 
}; 
... 
// Collecting set of product id's  
var selectedProductsIds = SelectedProducts.Select(p => p.Id).ToList(); 

// Filtering products 
q = q.WhereIn(c => c.Product.Id, selectedProductsIds);