Simplifying data search using .NET
- by Peter
An example on the asp.net site has an example of using Linq to create a search feature on a Music album site using MVC. The code looks like this -
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
I have seen similar examples in other tutorials and I have tried them in a real-world business app that I develop/maintain. In practice this pattern doesn't seem to scale well because as the search criteria expands I keep adding more and more conditions which looks and feels unpleasant/repetitive. How can I refactor this pattern?
One idea I have is to create a column in every table that is "searchable" which could be a computed column that concatenates all the data from the different columns (SQL Server 2008). So instead of having movie genre and title it would be something like.
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.SearchColumn.Contains(searchString));
}
What are the performance/design/architecture implications of doing this?
I have also tried using procedures that use dynamic queries but then I have just moved the ugliness to the database. E.g.
CREATE PROCEDURE [dbo].[search_music]
@title as varchar(50),
@genre as varchar(50)
AS
-- set the variables to null if they are empty
IF @title = '' SET @title = null
IF @genre = '' SET @genre = null
SELECT m.*
FROM view_Music as m
WHERE
(title = @title OR @title IS NULL)
AND (genre LIKE '%' + @genre + '%' OR @genre IS NULL)
ORDER BY Id desc
OPTION (RECOMPILE)
Any suggestions? Tips?