Search refinement for WebMatrix site

核能气质少年 提交于 2020-01-16 03:18:46

问题


I've been asking a few questions on this site, and have answers to lots of little bits, but I am now trying to piece the whole thing together.

I have a page where it shows all the properties I have in my database. I need to find a way to refine those results though, so for example, to only show properties that have 4 bedrooms etc. The problem is, I don't know how many variables I might have in the search term yet. So here's an example.

  1. a user may want to see ALL properties that just have 4 bedrooms
  2. a user may want to see ALL properties that have 4 bedrooms AND 3 bathrooms AND sleeps 8 people etc.

I have decided to pull all the variables from a query string, ?numbedrooms=4&?numbathrooms=3

Here's the code I have so far, but it doesn't work:

@{
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-->

So to clarify, I need to find a way to check to see if there is a query string entry for each search query, and if there is, append it to the SQL statement to see all results that match?


回答1:


Mainly, what it seems that you need is a good "user-interface" page.

Within that page, you have several form input elements (radio buttons, text boxes, checkboxes, etc.), where if left blank, they are ignored, but if not, you detect and append accordingly the SQL syntax you need to the SQL string.

For instance let's just say you had this form on the first (user-input) page (let's call it 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>

Of course, the viable options, and type of input fields on this form are totally maleable to your specific scenario, but you get the idea, I'm sure.

Next, in the part of the page2.cshtml file that begins to construct the SQL string:

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

Notice that this string, if nothing else were appended to it, would work fine and simply query for all entries in the database, without syntax error (SQL doesn't mind if there is an extra space at the end. This is good to know, because it will make your life easier down the road). However, now, you can start checking to see what info was passed to this page from the previous, and append to the SQL string accordingly.

Also, and perhaps the easiest way, to query the database while passing the appropriate number of unknown-until-runtime parameters, is to pass an array to the db.Query method. So, for each parameter that we test as valid, will be added to a list and later converted to array (we use a list first, because C# does not allow you to define an array with unknown size, but a list will allow you to add values as you go).

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.

Keep in mind that depending on how the data is stored in the database (nvarchar, int, etc.) you may have to use casting within the SQL string, parsing in C#, or simply adjust the way you write the selectQueryString, as you go, but I won't go into any further detail on that, because data types/conversions are out of the scope of this question.

Next we convert the list of arguments to an array.

int[] argArray = argList.ToArray();

Lastly, you just have to query the database. However, we also need to MAKE SURE that the array we sent the list to is not empty (which would most likely be caused by the list being empty when we converted it). I assure you, you will get a server-side error if you pass an empty array as the second argument to the db.Query() method.

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.
}

And really that's about it. The only thing is, there are a lot of things you may have to critique in order to get this working with your specific data types (as they are coming from the form page, but especially as they are stored within the database).



来源:https://stackoverflow.com/questions/18485241/search-refinement-for-webmatrix-site

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!