如何在LINQ-to-Entities 3.5中执行“where in values”

时间:2008-09-17 22:50:23

标签: linq linq-to-entities

是否有人知道如何使用LINQ-to-Entities应用“where in values”类型条件?我尝试了以下但是它不起作用:

var values = new[] { "String1", "String2" };  // some string values

var foo = model.entitySet.Where(e => values.Contains(e.Name));

我相信这可以在LINQ-to-SQL中使用吗?有什么想法吗?

7 个答案:

答案 0 :(得分:19)

更新:了解了如何执行此操作。 EF将在数据库上生成相应的SQL。我不确定这是否仅适用于EF4,但我从实体框架4.0食谱中得到了提示


var listOfIds=GetAListOfIds();
var context=CreateEntityFrameworkObjectContext();
var results = from item in context.Items
              where listOfIds.Contains(item.Category.Id)
              select item;
//results contains the items with matching category Ids

此查询在服务器端生成正确的in子句。我没有使用EF 3.5进行测试,但它确实适用于EF4。

NB:传入in子句的值不是参数,因此请确保验证输入。

答案 1 :(得分:1)

有点遗憾Contains is not supported in Linq to Entities

IN和JOIN不是同一个运算符(按IN过滤永远不会更改查询的基数)。

答案 2 :(得分:1)

此时EF不支持包含。

答案 3 :(得分:1)

供参考:

如果您使用的是ESql,则可以在操作中使用。 我没有VS 2008和我一起,但代码应该是以下内容:

var ids = "12, 34, 35";
using (context = new Entites())
{
    var selectedProducts = context.CreateQuery<Products>(
        String.Format("select value p from [Entities].Products as p 
                       where p.productId in {{{0}}}", ids)).ToList();
    ...
}

答案 4 :(得分:1)

对于在查询数据时要使用表达式的情况,可以使用以下扩展方法(在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<T> ExtWhereIn<T, TValue>(this ObjectQuery<T> query,
                    Expression<Func<T, TValue>> valueSelector,
                    IEnumerable<TValue> values) {
            return query.Where(BuildContainsExpression<T, TValue>(valueSelector, values));
        }
        public static IQueryable<T> ExtWhereIn<T, TValue>(this IQueryable<T> query,
            Expression<Func<T, TValue>> valueSelector,
            IEnumerable<TValue> values) {
            return query.Where(BuildContainsExpression<T, TValue>(valueSelector, values));
        }
        private static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(
                Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> 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<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
            return Expression.Lambda<Func<TElement, bool>>(body, p);
        }
    }
    class Program {
        static void Main(string[] args) {
            List<int> fullList = new List<int>();
            for (int i = 0; i < 20; i++) {
                fullList.Add(i);
            }

            List<int> filter = new List<int>();
            filter.Add(2);
            filter.Add(5);
            filter.Add(10);

            List<int> results = fullList.AsQueryable().ExtWhereIn<int, int>(item => item, filter).ToList();
            foreach (int result in results) {
                Console.WriteLine(result);
            }
        }
    }       
}

使用扩展非常简单(如示例中所示)。要在数据库对象上使用它,假设您正在通过多个id过滤名为“Product”的表,您可以执行以下操作:

class Product {
    public int Id { get; set; }
    /// ... other properties
}


List<Product> GetProducts(List<int> productIds) {    
    using (MyEntities context = new MyEntities()) {
        return context.Products.ExtWhereIn<Product, int>(product => product.Id, productIds).ToList();
    }
}

答案 5 :(得分:0)

是的,它确实转换为SQL,它生成一个标准的IN语句,如下所示:

SELECT [t0]。[col1] FROM [table] [t0] WHERE [col1] IN('值1','值2')

答案 6 :(得分:0)

使用where方法并不起作用

var results = from p in db.Products

             where p.Name == nameTextBox.Text

             select p;