带或算子的多动态条件

时间:2015-06-20 17:01:57

标签: sql sql-server asp.net-mvc linq entity-framework

我使用Entity Framework 5并且我使用了动态linq查询。但是我需要用" OR"来连接两个条件。运营商。例如,我可以在普通的sql文本中使用它。

SELECT * FROM Products WHERE 
(Keywords LIKE '%keyw1%' AND Keywords LIKE '%keyw2%') OR (ProdName LIKE '%ProdName%')

我的linq查询如下。但我需要动态创建条件。 我怎么能这样做?

var prodQuery = from p in _db.Products
    select p;

searchText.Split(' ')
    .ForEach(
        s =>
            prodQuery =
                prodQuery.Where(
                    p => p.Product.Keywords.Contains(s)));

//i need here "OR" operator. I have to connect this line with "OR" to upper condition
prodQuery = prodQuery.Where(p => p.ProdName.Contains("test prod"))  

2 个答案:

答案 0 :(得分:0)

你有没有试过像:

string[] searchTerms = searchText.Split(' ');
var prodQuery = _db.Products.Any(p => 
    p.Product.Keywords.Any(k => searchTerms.Contains(k)) 
    || searchTerms.Contains(p.ProdName)
);

这是一个适合你的清洁版本:

key     = ']\n\x80\xd8\x13J\xe1\x96w\x82Kg\x1e\x83\x8a\xf4'

答案 1 :(得分:0)

您应该做的是在表达式树中构建查询条件,然后将其应用于linq对象。

您可以使用此PredicateBuilder类来执行此操作。

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>> (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}

现在你的代码:

var prodQuery = from p in _db.Products
   select p;

var condition = PredicateBuilder.False<Product>();

searchText.Split(' ')
    .ForEach(s => condition = condition.And(p => p.Product.Keywords.Contains(s)));

condition = condition.Or(p => p.ProdName.Contains("test prod"));
prodQuery = prodQuery.Where(condition);