How to do a “where in values” in LINQ-to-Entities 3.5

前端 未结 7 1340
时光说笑
时光说笑 2020-12-15 18:42

Does anybody know how to apply a \"where in values\" type condition using LINQ-to-Entities? I\'ve tried the following but it doesn\'t work:

var values = new         


        
7条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-15 19:19

    For the cases when you want to use expressions when querying your data, you can use the following extension method (adapted after http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/095745fe-dcf0-4142-b684-b7e4a1ab59f0/):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Data.Objects;
    
    namespace Sample {
        public static class Extensions {
            public static IQueryable ExtWhereIn(this ObjectQuery query,
                        Expression> valueSelector,
                        IEnumerable values) {
                return query.Where(BuildContainsExpression(valueSelector, values));
            }
            public static IQueryable ExtWhereIn(this IQueryable query,
                Expression> valueSelector,
                IEnumerable values) {
                return query.Where(BuildContainsExpression(valueSelector, values));
            }
            private static Expression> BuildContainsExpression(
                    Expression> valueSelector, IEnumerable values) {
                if (null == valueSelector) { throw new ArgumentNullException("valueSelector"); }
                if (null == values) { throw new ArgumentNullException("values"); }
                ParameterExpression p = valueSelector.Parameters.Single();
                // p => valueSelector(p) == values[0] || valueSelector(p) == ...
                if (!values.Any()) {
                    return e => false;
                }
                var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
                var body = equals.Aggregate((accumulate, equal) => Expression.Or(accumulate, equal));
                return Expression.Lambda>(body, p);
            }
        }
        class Program {
            static void Main(string[] args) {
                List fullList = new List();
                for (int i = 0; i < 20; i++) {
                    fullList.Add(i);
                }
    
                List filter = new List();
                filter.Add(2);
                filter.Add(5);
                filter.Add(10);
    
                List results = fullList.AsQueryable().ExtWhereIn(item => item, filter).ToList();
                foreach (int result in results) {
                    Console.WriteLine(result);
                }
            }
        }       
    }
    

    Using the extensions is really easy (as you can see in the sample). To use it on a database object, assuming you are filtering a table called "Product" by more than one id, you could do something like that:

    class Product {
        public int Id { get; set; }
        /// ... other properties
    }
    
    
    List GetProducts(List productIds) {    
        using (MyEntities context = new MyEntities()) {
            return context.Products.ExtWhereIn(product => product.Id, productIds).ToList();
        }
    }
    

提交回复
热议问题