I have an ASP.NET MVC website. In my backend I have a table called People with the following columns:
- ID
- Name
- Age
- Location
- … (a number of other cols)
I have a generic web page that uses model binding to query this data. Here is my controller action:
public ActionResult GetData(FilterParams filterParams)
{
return View(_dataAccess.Retrieve(filterParams.Name, filterParams.Age, filterParams.location, . . .)
}
which maps onto something like this:
http://www.mysite.com/MyController/GetData?Name=Bill .. .
The dataAccess layer simply checks each parameter to see if its populated to add to the db where clause. This works great.
I now want to be able to store a user’s filtered queries and I am trying to figure out the best way to store a specific filter. As some of the filters only have one param in the queryString while others have 10+ fields in the filter I can’t figure out the most elegant way to storing this query “filter info” into my database.
Options I can think of are:
-
Have a complete replicate of the table (with some extra cols) but call it PeopleFilterQueries and populate in each record a FilterName and put the value of the filter in each of field (Name, etc)
-
Store a table with just FilterName and a string where I store the actual querystring Name=Bill&Location=NewYork. This way I won’t have to keep adding new columns if the filters change or grow.
What is the best practice for this situation?
If the purpose is to save a list of recently used filters, I would serialise the complete FilterParams object into an XML field/column after the model binding has occurred. By saving it into a XML field you’re also giving yourself the flexibility to use XQuery and DML should the need arise at a later date for more performance focused querying of the information.
And then in your DataAccess Class you’ll want to have two Methods, one for saving and one for retrieving the filters:
Then when you want to retrieve a saved filter, perhaps by Id:
Remember that your FilterParams class must have a default (i.e. parameterless) constructor, and you can use the
[XmlIgnore]attribute to prevent properties from being serialised into the database should you wish.Note: The SaveFilter returns Void and there is no error handling for brevity.