在LINQ to SQL中将多个复杂的WHERE子句链接在一起

时间:2010-07-16 16:06:35

标签: c# linq linq-to-sql linq-to-entities

这是我想要生成的伪SQL:

SELECT * FROM Table WHERE Column1 = @Value1 OR Column2 = @Value2

问题是,有时不应包括第二个。我希望将.Where()条款链接在一起:

var query = context.TableName;
query = query.Where(t => t.Column1 == value1);
if (NeedsToBeIncluded(value2))
  query = query.Where(t => t.Column2 == value2);

不幸的是,这不起作用。如果您默认将它们链接在一起,.Where()将发出AND。有没有办法让它发出OR

我正在寻找以下内容:

var query = context.TableName;
query = query.Where(t => t.Column1 == value1);
if (NeedsToBeIncluded(value2))
  query = query.OrWhere(t => t.Column2 == value2);

更新 好的,所以我上面列出的例子太简单了。它只是一个概述问题空间的例子。可以说,“在野外”,Column1和Column2实际上可能是“CarType”和“OwnerName”,也许还有更多,也许还有更少。我只是用一个简单的例子来概述问题,因为我希望用这个链接来解决一系列域问题 - .Where() s。

2 个答案:

答案 0 :(得分:10)

一种方法是使用LINQKit的PredicateBuilder

另一种方法是使用列表:

var values = new List<string> { value1 };
if (NeedsToBeIncluded(value2)) values.Add(value2);
query = context.TableName.Where(t => values.Contains(t));

PB更灵活,但列表将解决您问题中的问题。请注意,Contains需要EF 4。

答案 1 :(得分:3)

我举了一个例子,说明昨天如何动态建立一个条件 - 见here。对于你的情况,它会是这样的。

var parameter = Expression.Parameter(typeof(TableName), "t");

Expression condition = Expression.Equal(
    Expression.Property(parameter, "Column1"),
    Expression.Constant(value1)));

if (NeedsToBeIncluded(value2))
{
    condition = Expression.OrElse(
        condition,
        Expression.Equal(
            Expression.Property(parameter, "Column2"),
            Expression.Constant(value2)));
}

var expression = Expression.Lambda<Func<TableName, Boolean>>(condition, parameter);

var query = context.TableName.Where(expression);