Reputation: 2489
I have an object BookData:
public class BookData
{
public BookData();
public string[] Authors{ get; set; }
public string Genre { get; set; }
public int BookId { get; set; }
public int PublishedDate{ get; set; }
public string Title { get; set; }
}
I'm trying to implement a function where I can search by any of the properties/fields in the book object.
For example, to return all the books where PublishedDate=2016 and Genre="Thriller". How do I make a dynamic search method as the number of search fields may differ. E.g. I can search using all the fields or just one.
public IList<BookData> SearchBookBy( arguments ) {
//return list of books which match the search criteria
//e.g. Title contains "love" AND Genre="Romance" AND PublishDate=2015
}
So far, I have something like this:
public IList<BookData> ListBooksBy(string title, string genre, int publishedDate, int bookId, string author)
{
var books = ListAllBooks();
var bk = from m in books
select m;
bk = books.Where(
(s =>
(s.Title.ToUpper().Contains(title.ToUpper()))
|| (s.BookId.ToString().Contains(bookId))
|| (s.Genre.ToUpper().Contains(genre.ToUpper()))
|| (s.PublishedDate.ToString().Contains(publishedDate))
|| (s.Authors.ToString().Contains(author))
)).ToList();
books. bk.ToList();
return books;
}
But the above isn't dynamic, and surely there is a better/cleaner way of doing this.
Would be very grateful if you can help as I'm very new to this.
Thanks in advance.
Upvotes: 2
Views: 922
Reputation: 1308
As mentioned in the comments above you can do this with expression trees. It will do what you need to do, but it may not be completely feasible, depending upon the size of your dataset; if you do expression trees you are doing the filtering in memory which may cause performance issues if you have large datasets.
Another option is to do the filtering in a stored procedure. Using SQL Server, for instance, you can default your parameters to NULL like this:
@Authors VARCHAR(50) = NULL,
@Genre VARCHAR(50) = NULL,
@BookId VARCHAR(50) = NULL,
@PublishedDate VARCHAR(50) = NULL,
@Title VARCHAR(50) = NULL
And then filter in your where clause:
WHERE (Authors LIKE @Authors OR @Authors IS NULL)
AND (Genre LIKE @Genre OR @Genre IS NULL)
AND (BookId LIKE @BookId OR @BookId IS NULL)
AND (PublishedDate LIKE @PublishedDate OR @PublishedDate IS NULL)
AND (Title LIKE @Title OR @Title IS NULL)
That makes for some ugly SQL, and you should probably clean up the data types, but you get the idea. Going the SQL route is not really sustainable for a large number of search parameters.
If you decide to go the expression tree route, I have a demo project I wrote for a presentation that you might be able to use as a starting point:
Hope that helps
Upvotes: 2