2009-06-10 54 views
32

的地方我一直在尋找谷歌,但沒有找到任何對我有用的技巧。LINQ在收集條款

如你所知SQL有一個「where x in(1,2,3)」子句,它允許你檢查多個值。 我正在使用linq,但我似乎無法找到與上述語句相同的語法。

我有類別的ID(列表)的集合,一個我想檢查

我發現一些使用。載方法,但它甚至不建。

回答

40

您必須使用包含方法您的ID列表:

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

雖然我有一個跟進。 id的列是可以爲空的(我通過使用value屬性來忘記和修復) 如果值爲null,會發生什麼情況? – 2009-06-10 06:22:25

3

下面是說明該方法的article。您的確應該對您的收藏使用Contains方法,該方法將被翻譯爲IN條款。

+5

鏈接的文章沒有更長的存在。 – MattD 2016-05-20 16:06:44

18

的語法如下:

IEnumerable<int> categoryIds = yourListOfIds; 

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

要注意的關鍵問題是,你做的包含您的名單上ids - 如果您正在編寫sql,則不在要應用in的對象上。

1

這是我實現的,其中()方法,由一組選定的實體篩選IQueryable的集合:

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; 
    } 

而且這種方法的調用看起來像:

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);