Linq to Entities - SQL “IN” clause

前端 未结 8 1257
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 05:10

In T-SQL you could have a query like:

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

How would you replicate t

8条回答
  •  逝去的感伤
    2020-11-22 05:49

    An alternative method to BenAlabaster answer

    First of all, you can rewrite the query like this:

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

    Certainly this is more 'wordy' and a pain to write but it works all the same.

    So if we had some utility method that made it easy to create these kind of LINQ expressions we'd be in business.

    with a utility method in place you can write something like this:

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

    This builds an expression that has the same effect as:

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

    But which more importantly actually works against .NET 3.5 SP1.

    Here is the plumbing function that makes this possible:

    public static Expression> BuildOrExpression(
            Expression> valueSelector, 
            IEnumerable 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(
                (accumulate, equal) => Expression.Or(accumulate, equal)
        ); 
    
       return Expression.Lambda>(body, p);
    }
    

    I'm not going to try to explain this method, other than to say it essentially builds a predicate expression for all the values using the valueSelector (i.e. p => p.User_Rights) and ORs those predicates together to create an expression for the complete predicate

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

提交回复
热议问题