Thursday, April 14, 2011

How to query multiple entities at once?

I'm trying to query an Entity to return multiple rows based on a filter.

For instance in SQL we have:

SELECT * FROM table WHERE field IN (1, 2, 3)

How do I do it in LINQ to Entities?

From stackoverflow
  • This is an exact representation of the query you have in SQL.

    int[] productList = new int[] { 1, 2, 3};

    var myProducts = from p in db.Products
                     where productList.Contains(p.ProductID)
                    select p;
    

    If it were entities, could you describe the problem better?

    The exact SQL representation would be...

    SELECT [t0].[ProductID], [t0].[Name], [t0].[ProductNumber], [t0].[MakeFlag], [t0].[FinishedGoodsFlag], 
    [t0].[Color], [t0].[SafetyStockLevel], [t0].[ReorderPoint], [t0].[StandardCost], [t0].[ListPrice], 
    [t0].[Size], [t0].[SizeUnitMeasureCode], [t0].[WeightUnitMeasureCode], [t0].[Weight], [t0].[DaysToManufacture], 
    [t0].[ProductLine], [t0].[Class], [t0].[Style], [t0].[ProductSubcategoryID], [t0].[ProductModelID], 
    [t0].[SellStartDate], [t0].[SellEndDate], [t0].[DiscontinuedDate], [t0].[rowguid], [t0].[ModifiedDate]
    FROM [Production].[Product] AS [t0]
    WHERE [t0].[ProductID] IN (@p0, @p1, @p2, @p3)
    
  • you could do something like this:

    int[] productList = new int[] { 1, 2, 3, 4 };
    
    var myProducts = from p in db.Products
                     where productList.Contains(p.ProductID)
                    select p;
    
    Oscar Cabrero : +1 for the fast writting
    Paulo Santos : When I use this method I recieve the following error: LINQ to Entities does not recognize the method 'Boolean Contains[Int32](System.Collections.Generic.IEnumerable`1[System.Int32], Int32)' method, and this method cannot be translated into a store expression
  • Although I did recieved some prompt answers, and I thank you all for that. The method shown on the replies I've got didn't work.

    I had to keep searching until I eventually found a way to do what I needed in a post from Frederic Ouellet at Microsoft Forums.

    In short it's the extension method below:

        public static IQueryable<T> WhereIn<T, TValue>(this IQueryable<T> source, Expression<Func<T, TValue>> propertySelector, params TValue[] values)
        {
            return source.Where(GetWhereInExpression(propertySelector, values));
        }
    
        public static IQueryable<T> WhereIn<T, TValue>(this IQueryable<T> source, Expression<Func<T, TValue>> propertySelector, IEnumerable<TValue> values)
        {
            return source.Where(GetWhereInExpression(propertySelector, values));
        }
    
        private static Expression<Func<T, bool>> GetWhereInExpression<T, TValue>(Expression<Func<T, TValue>> propertySelector, IEnumerable<TValue> values)
        {
            ParameterExpression p = propertySelector.Parameters.Single();
            if (!values.Any())
                return e => false;
    
            var equals = values.Select(value => (Expression)Expression.Equal(propertySelector.Body, Expression.Constant(value, typeof(TValue))));
            var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
    
            return Expression.Lambda<Func<T, bool>>(body, p);
        }
    

0 comments:

Post a Comment