1

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

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

  1. 用户可能想查看所有只有 4 间卧室的房产
  2. 用户可能希望查看所有具有 4 间卧室和 3 间浴室并睡 8 人等的房产。

我决定从查询字符串 ?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 语句中以查看所有匹配的结果?

4

1 回答 1

2

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

在该页面中,您有几个表单输入元素(单选按钮、文本框、复选框等),如果留空,它们将被忽略,但如果没有,您将检测并相应地附加您需要的 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>

当然,此表单上的可行选项和输入字段类型完全适合您的特定场景,但您明白这一点,我敢肯定。

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

/*[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();

最后,您只需要查询数据库。但是,我们还需要确保我们将列表发送到的数组不为空(这很可能是由于我们转换列表时列表为空造成的)。我向您保证,如果您将空数组作为第二个参数传递给该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.
}

真的就是这样。唯一的问题是,您可能需要批评很多事情才能使其与您的特定数据类型一起使用(因为它们来自表单页面,但特别是当它们存储在数据库中时)。

于 2013-09-03T15:48:55.457 回答