搜索WebMatrix站点的优化

时间:2013-08-28 10:21:36

标签: sql arrays razor query-string webmatrix

我一直在这个网站上问几个问题,并且有很多小问题的答案,但我现在正试图将整个事情拼凑起来。

我有一个页面,其中显示了我在数据库中的所有属性。我需要找到一种方法来改进这些结果,所以例如,只显示有4间卧室等的属性。问题是,我不知道我可能在搜索词中有多少变量。所以这是一个例子。

  1. 用户可能希望查看只有4间卧室的所有房产
  2. 用户可能希望查看所有具有4间卧室和3间浴室并且可容纳8人等的房产。
  3. 我决定从查询字符串中提取所有变量,?numbedrooms = 4&?numbathrooms = 3

    这是我到目前为止的代码,但它不起作用:

    @{
    var db = Database.Open("StayInFlorida");
    
    IEnumerable<dynamic> queryResults;
    
    int numBedrooms = Request.QueryString["numBedrooms"].AsInt();
    int numBathrooms = Request.QueryString["numBathrooms"].AsInt();
    int sleeps = 0;
    
    List<int> argList = new List<int>();
    
    if (Request.QueryString["sleeps"].IsInt())
    {
    sleeps = Request.QueryString["sleeps"].AsInt();
    }
    
    int numOfArguments = 0;
    
    string selectQueryString = "SELECT * FROM PropertyInfo ";
    
    if (numBedrooms != 0)
    {
    argList.Add(numBedrooms);
    selectQueryString += "WHERE numBedrooms = @0 ";
    
    numOfArguments++; //increment numOfArguments by 1
    }
    
    if (numBathrooms != 0)
    {
    argList.Add(numBathrooms);
    if (numOfArguments == 0)
    {
        selectQueryString += "WHERE numBathrooms = @0 ";
    }
    else
    {
        selectQueryString += "AND numBathrooms = @" + numOfArguments + " ";
    }
    numOfArguments++;
    }
    
    if (sleeps != 0)
    {
    argList.Add(sleeps);
    if (numOfArguments == 0)
    {
        selectQueryString += "WHERE sleeps = @0 ";
    }
    else
    {
        selectQueryString += "AND sleeps = @" + numOfArguments + " ";
    }
    numOfArguments++;
    }
    
    selectQueryString += "ORDER BY numBedrooms DESC"; //Adjust this order by clause how you see fit.
    
    int[] argArray = argList.ToArray();
    
    if (argArray.Length > 0)
    {
    queryResults = db.Query(selectQueryString, argArray); //stores a dynamic list to 'queryResults' which can later be easily iterated through with a 'foreach' list and written to the page with razor.
    }
    }
    
    
    
    <!--Results Start-->
    
    @foreach(var row in queryResults){
    <div class="container">
    
                    <h4><a href="/property.cshtml?propertyid=@row.PropertyID">@row.PropertyName</a></h4>
                    <h5>Bedrooms: @row.NumBedrooms Bathrooms: @row.NumBathrooms Sleeps: @row.NumSleeps</h5>
    
    
    </div>
    }
    <!--Results Finish-->
    

    因此,为了澄清,我需要找到一种方法来检查每个搜索查询是否有查询字符串条目,如果有,请将其附加到SQL语句以查看匹配的所有结果?

    Pleeeeeease帮助,我已经坚持了很长时间。

    非常感谢

1 个答案:

答案 0 :(得分:1)

主要是,您需要的是一个很好的“用户界面”页面。

在该页面中,您有多个表单输入元素(单选按钮,文本框,复选框等),如果留空,则会被忽略,但如果没有,则会相应地检测并附加您需要的SQL语法SQL字符串。

例如,我们只是说你在第一个(用户输入)页面上有这个表单(我们称之为page1.cshtml):

<!--[HTML]-->
<form action="~/page2.cshtml" method="GET">
    <select name="numBedrooms">
        <option value="0">Please Select</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>
    <select name="numBathrooms">
        <option value="0">Please Select</option>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>
    <input type="text" maxlength="3" name="sleeps" />
</form>

当然,这个表单上的可行选项和输入字段类型完全可以根据您的具体情况进行调整,但是您明白了。

接下来,在开始构造SQL字符串的page2.cshtml文件部分中:

/*[C#]*/
var db = Database.Open("StayInFlorida");
int numBedrooms = Request.QueryString["numBedrooms"].AsInt();
int numBathrooms = Request.QueryString["numBathrooms"].AsInt();
int sleeps = 0;
List<int> argList = new List<int>();

if (Request.QueryString["sleeps"].IsInt())
{
    sleeps = Request.QueryString["sleeps"].AsInt();
}

int numOfArguments = 0;

string selectQueryString = "SELECT * FROM PropertyInfo ";

请注意,如果没有附加任何其他内容,此字符串将正常工作,只需查询数据库中的所有条目,而不会出现语法错误(SQL不介意最后是否有额外的空格。这是很高兴知道,因为它会让你的生活更轻松。)但是,现在,您可以开始检查从前一个页面传递到此页面的信息,并相应地附加到SQL字符串。

此外,也许最简单的方法是,在传递适当数量的 unknown-until-runtime 参数的同时查询数据库,就是将数组传递给db.Query方法。因此,对于我们测试为有效的每个参数,将被添加到列表中,然后转换为数组(我们首先使用列表,因为C#不允许您定义具有未知大小的数组,但是列表将允许您随时添加值。)

if (numBedrooms != 0)
{
    argList.Add(numBedrooms);
    selectQueryString += "WHERE numBedrooms = @0 ";

    numOfArguments++; //increment numOfArguments by 1
}

if (numBathrooms != "0")
{
    argList.Add(numBathrooms);
    if (numOfArguments == 0)
    {
        selectQueryString += "WHERE numBathrooms = @0 ";
    }
    else
    {
        selectQueryString += "AND numBathrooms = @" + numOfArguments + " ";
    }
    numOfArguments++;
}

if (sleeps != 0)
{
    argList.Add(sleeps);
    if (numOfArguments == 0)
    {
        selectQueryString += "WHERE sleeps = @0 ";
    }
    else
    {
        selectQueryString += "AND sleeps = @" + numOfArguments + " ";
    }
    numOfArguments++;
}

selectQueryString += "ORDER BY numBedrooms DESC"; //Adjust this order by clause how you see fit.

请记住,根据数据在数据库中的存储方式(nvarchar,int等),您可能必须在SQL字符串中使用强制转换,在C#中进行解析,或者只是调整编写selectQueryString的方式,如你所愿,但我不会详细介绍,因为数据类型/转换超出了这个问题的范围。

接下来,我们将参数列表转换为数组。

int[] argArray = argList.ToArray();

最后,您只需查询数据库即可。但是,我们还需要 MAKE SURE 我们发送列表的数组不是空的(这很可能是由于我们转换它时列表为空)。我向你保证,如果你将一个空数组作为db.Query()方法的第二个参数传递,你将收到服务器端错误。

if (argArray.Length > 0)
{
    var queryResults = db.Query(selectQueryString, argArray); //stores a dynamic list to 'queryResults' which can later be easily iterated through with a 'foreach' list and written to the page with razor.

    //put your "foreach (var row in queryResults)" loop here.
}

真的就是这个。唯一的问题是,为了使这种方法与特定的数据类型一起工作,你可能需要批评很多东西(因为它们来自表单页面,但特别是当它们存储在数据库中时)。

希望这至少可以让您更接近实现目标。如果您需要更多帮助,还有其他问题或(尽管我尽了最大努力)发现语法或其他错误,请告诉我。

快乐的编码,加文!