在T-SQL中,你可以有这样的查询:

SELECT * FROM Users WHERE User_Rights IN ("Admin", "User", "Limited")

如何复制在一个LINQ实体查询?这可能吗?


当前回答

一个替代BenAlabaster回答的方法

首先,你可以像这样重写查询:

var matches = from Users in people
        where Users.User_Rights == "Admin" ||
              Users.User_Rights == "Users" || 
              Users.User_Rights == "Limited"
        select Users;

当然,这更“啰嗦”,写起来很痛苦,但它仍然有效。

因此,如果我们有一些实用方法,可以很容易地创建这些LINQ表达式,我们就可以开始工作了。

有了实用工具方法,你可以这样写:

var matches = ctx.People.Where(
        BuildOrExpression<People, string>(
           p => p.User_Rights, names
        )
);

这将构建一个具有相同效果的表达式:

var matches = from p in ctx.People
        where names.Contains(p.User_Rights)
        select p;

但更重要的是,它实际上适用于。net 3.5 SP1。

下面是管道功能,使这成为可能:

public static Expression<Func<TElement, bool>> BuildOrExpression<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();

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

我不打算解释这个方法,只是说它本质上使用valueSelector(即p => p.User_Rights)为所有值构建一个谓词表达式,并将这些谓词or在一起,为完整的谓词创建一个表达式

来源:http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx

其他回答

严重吗?你们从没用过

where (t.MyTableId == 1 || t.MyTableId == 2 || t.MyTableId == 3)

一个替代BenAlabaster回答的方法

首先,你可以像这样重写查询:

var matches = from Users in people
        where Users.User_Rights == "Admin" ||
              Users.User_Rights == "Users" || 
              Users.User_Rights == "Limited"
        select Users;

当然,这更“啰嗦”,写起来很痛苦,但它仍然有效。

因此,如果我们有一些实用方法,可以很容易地创建这些LINQ表达式,我们就可以开始工作了。

有了实用工具方法,你可以这样写:

var matches = ctx.People.Where(
        BuildOrExpression<People, string>(
           p => p.User_Rights, names
        )
);

这将构建一个具有相同效果的表达式:

var matches = from p in ctx.People
        where names.Contains(p.User_Rights)
        select p;

但更重要的是,它实际上适用于。net 3.5 SP1。

下面是管道功能,使这成为可能:

public static Expression<Func<TElement, bool>> BuildOrExpression<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();

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

我不打算解释这个方法,只是说它本质上使用valueSelector(即p => p.User_Rights)为所有值构建一个谓词表达式,并将这些谓词or在一起,为完整的谓词创建一个表达式

来源:http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx

这应该够你的目的了。它比较两个集合,并检查其中一个集合的值是否与另一个集合中的值匹配

fea_Features.Where(s => selectedFeatures.Contains(s.feaId))

这可能是直接使用LINQ扩展方法检查in子句的可能方式

var result = _db.Companies.Where(c => _db.CurrentSessionVariableDetails.Select(s => s.CompanyId).Contains(c.Id)).ToList();

真实的例子:

var trackList = Model.TrackingHistory.GroupBy(x => x.ShipmentStatusId).Select(x => x.Last()).Reverse();
List<int> done_step1 = new List<int>() {2,3,4,5,6,7,8,9,10,11,14,18,21,22,23,24,25,26 };
bool isExists = trackList.Where(x => done_step1.Contains(x.ShipmentStatusId.Value)).FirstOrDefault() != null;