Sql 具有动态布尔AND数的LINQ查询

Sql 具有动态布尔AND数的LINQ查询,sql,linq,linq-to-sql,Sql,Linq,Linq To Sql,我正在为我的网站制作搜索网页。该要求规定,用户可以为9+个字段的任意组合输入文本,在查询数据库时,搜索应进行“和”匹配。我可以相当快地使用'ISNULL'将其作为存储过程编写,但我正在尝试找出如何在LINQ中完成同样的事情。我以为我可以查询查询的结果,但我得到了错误 String.Contains方法只支持可在客户端上计算的参数 这是我的例子 var people = db.People if(null != fname) { people= from e in people where

我正在为我的网站制作搜索网页。该要求规定,用户可以为9+个字段的任意组合输入文本,在查询数据库时,搜索应进行“和”匹配。我可以相当快地使用'ISNULL'将其作为存储过程编写,但我正在尝试找出如何在LINQ中完成同样的事情。我以为我可以查询查询的结果,但我得到了错误

String.Contains方法只支持可在客户端上计算的参数

这是我的例子

var people = db.People

if(null != fname)
{
people= from e in people
   where e.FirstName.Contains(fname)
   select e;
}

if(null != lname)
{
people= from e in people
   where e.LastName.Contains(lname)
   select e;
}

return people;
我可以查询上一次查询的结果集吗?有没有更好的方法我只是没想到

提前感谢。

您的fname和lname是如何定义的

您应该在此处查看PredicateBuilder,尤其是如果您还需要或在某个时候:

您的fname和lname是如何定义的

您应该在此处查看PredicateBuilder,尤其是如果您还需要或在某个时候:


这应该是可行的,而且似乎更简单:

people = from e in db.People
    where (lname == null || e.LastName.Contains(lname))
       && (fname == null || e.FirstName.Contains(fname))
    select e;

您提供的代码没有任何明显的错误,因为您没有理由不能查询其他查询的结果。看起来fname或lname是以SQL生成器不理解的方式定义的。

这应该可以工作,而且看起来更简单:

people = from e in db.People
    where (lname == null || e.LastName.Contains(lname))
       && (fname == null || e.FirstName.Contains(fname))
    select e;
您提供的代码没有任何明显的错误,因为您没有理由不能查询其他查询的结果。看起来fname或lname的定义方式是SQL生成器无法理解的。

这应该可以做到:

var people = db.People;
if(!String.IsNullOrEmpty(fname))
    people = people.Where(p => p.FirstName.Contains(fname));
if(!String.IsNullOrEmpty(lname))
    people = people.Where(p => p.LastName.Contains(lname));
return people;
这应该做到:

var people = db.People;
if(!String.IsNullOrEmpty(fname))
    people = people.Where(p => p.FirstName.Contains(fname));
if(!String.IsNullOrEmpty(lname))
    people = people.Where(p => p.LastName.Contains(lname));
return people;

有时,我会通过直接调用扩展方法,在更少的行中完成同样的事情:

var people = from e in db.People select e;

if(null != fname)
{
   people = people.Where(e => e.FirstName.Contains(fname));
}

if(null != lname)
{
    people = people.Where(e => e.LastName.Contains(lname));
}

return people;

有时,我会通过直接调用扩展方法,在更少的行中完成同样的事情:

var people = from e in db.People select e;

if(null != fname)
{
   people = people.Where(e => e.FirstName.Contains(fname));
}

if(null != lname)
{
    people = people.Where(e => e.LastName.Contains(lname));
}

return people;

+1,很好的解决方案,它在Linq到Sql中工作。仅供参考,我以前使用LLBLGen时遇到过这种模式的问题。如果以与上面相同的形式将其传递给SQL,它将运行badly@Craig:如果这解决了您的问题,请将其标记为答案。gbn:这将如何比任何其他查询运行得更糟糕?在没有表扫描的情况下,无法运行这样的查询,而且这可能比查询的任何其他部分都要慢几个数量级。因为这被解释为SQL,Gabe认为这无关紧要是正确的。然而,我通常在最初的提交中使用这种方法,因为当处理在.Net端实际运行的列表时,它可能会产生微不足道的影响。对我来说,以增量方式构建它似乎更为简洁,尤其是当您最终拥有的条件不止是几个时。+1,这是一个很好的解决方案,它在LINQtoSQL中工作。仅供参考,我以前使用LLBLGen时遇到过这种模式的问题。如果以与上面相同的形式将其传递给SQL,它将运行badly@Craig:如果这解决了您的问题,请将其标记为答案。gbn:这将如何比任何其他查询运行得更糟糕?在没有表扫描的情况下,无法运行这样的查询,而且这可能比查询的任何其他部分都要慢几个数量级。因为这被解释为SQL,Gabe认为这无关紧要是正确的。然而,我通常在最初的提交中使用这种方法,因为当处理在.Net端实际运行的列表时,它可能会产生微不足道的影响。对我来说,以增量的方式构建它似乎更为干净,尤其是当你最终拥有的不仅仅是几个条件时。