Linq查询到db with dynamic where参数

时间:2014-07-29 19:06:16

标签: c# asp.net-mvc linq wildcard

我有一张包含城市数据的表格: 在搜索输入字段中,用户键入任意数量的字符,然后按"搜索"按钮。 还有另一个字段,用户可以通过下拉列表进入州。

按下搜索按钮会触发对服务器控制器的ajax调用,该控制器接收名称的起始字符和状态的两个字符。

控制器应返回名称以提供的字符开头的城市列表。 如果状态通过,则列表应仅包含名称以提供的字符AND开头且位于该状态的城市。

如果状态未通过,则无论状态如何,都会返回所有匹配的城市。

我找不到编写单个Linq语句的方法,因为我不知道如何编写状态查询的部分: 目前我这样做:

public ActionResult selectCity(string searchString, string stateCode)
{
    List<CityViewModel> mylist = new List<CityViewModel>();
    IQueryable<City> mycities = null;

    if (stateCode == "")
    {
        mylist = (from c in db.Cities
                    where c.name.StartsWith(searchString)
                    select c);
    }
    else
    {
        mylist = (from c in db.Cities
                    where ((c.name.StartsWith(searchString)) &&
                          (c.stateCode == stateCode))
                    select c);
    }

    <snip>
    .....
    .....
    </snip>

   return PartialView("_selComune",elenco);
}

我无法相信单一查询无法做到这一点。

2 个答案:

答案 0 :(得分:3)

是的,有。

您希望:如果stateCode为空或匹配City.stateCode,则将其包含在结果中City.Name必须始终以searchString开头}。在代码中:

var mylist = 
    from c in db.Cities
    where 
        c.name.StartsWith(searchString) 
        && (stateCode == "" || c.stateCode == stateCode)
    select c;

大致相当于这个SQL(假设提供了具有正确语法的参数):

SELECT * FROM Cities
WHERE name LIKE @searchString AND (@stateCode = '' OR stateCode = @stateCode)

如果始终满足第一个条件,SQL Server将优化第二个比较(只需检查查询执行计划)。

<小时/> <子> 我认为这是一个拼写错误编写代码示例,但myList不是List<City>,除非您还将ToList()添加到LINQ查询中。

答案 1 :(得分:0)

Adriano Repetti的回答允许您编写单个查询来处理&#34; nullable&#34;参数但有时它有性能上的缺点,在SQL中翻译的那种查询可能会阻止索引工作。

请注意,以下内容也可以在sql端运行并构建所需的查询,LINQ端只需要一些代码:

    mylist = (from c in db.Cities
              where c.name.StartsWith(searchString)
              select c);

    if (stateCode != "")
    {
        mylist = mylist.Where(c.stateCode == stateCode);
    }

这种结构不会取代以前的&#34;其中&#34;内容,它将添加任何新的术语,将它们与&#34;和&#34;运营商。

允许您在许多不同的行中构建它,而不是像在代码示例中那样构建它。