2009-06-10 14 views
32

He estado buscando en google pero no he encontrado nada que me solucione el problema.LINQ Donde en la cláusula de recopilación

como usted sabe SQL tiene una cláusula "where x in (1,2,3)" que le permite consultar contra valores múltiples. Estoy usando linq pero parece que no puedo encontrar una sintaxis que haga lo mismo que la declaración anterior.

Tengo una colección de categoría de Identificación (Lista) contra la que me gustaría comprobar

he encontrado algo que utiliza el método .contains pero ni siquiera se construyo.

Respuesta

40

usted tiene que utilizar el método contiene en su lista Identificación:

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

Aunque tengo un seguimiento. la columna de id es anulable (lo cual olvidé y solucioné usando la propiedad value) ¿Qué sucede si el valor es nulo? –

+1

Si el valor t.Id es nulo, el resultado no incluirá este registro. –

3

Aquí hay un article que ilustra el enfoque. De hecho, debe utilizar el método Contiene sobre su colección, que se traducirá en la cláusula IN.

+5

El artículo enlazado sin mas tiempo existe – MattD

18

La sintaxis es a continuación:

IEnumerable<int> categoryIds = yourListOfIds; 

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

La clave para tener en cuenta es que haga lo contiene en su lista de ids: no en el objeto al que aplicarías la entrada si estuvieras escribiendo sql.

1

Aquí es mi realización de la que() Método para filtrar colección IQueryable por un conjunto de entidades seleccionadas:

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

y el llamamiento de este método se parece a:

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