I have this controller method:
public ActionResult Index(string searchError)
{
// get all errors
var viewModel = _errorsRepository.Errors.OrderByDescending(e => e.TimeUtc).
Select(e => new ErrorViewModel
{
ErrorId = e.ErrorId,
Message = e.Message,
TimeUtc = e.TimeUtc
});
if (!String.IsNullOrEmpty(searchError))
viewModel = viewModel.Where(e => e.Message.ToLower().Contains(searchError.Trim().ToLower()));
return View(viewModel);
}
I think doing the extra filter is slowing everything down, I was wondering if I can add the Where clause to the Select statement and check to see if searchError is null inline.
Is this possible?
Since Linq is lazy it does not matter if you have “one big statement” or multiple, as long as you don’t execute your query (e.g. by iterating over the results or forcing eager execution using
ToList()) there is no penalty since you are just chaining extension methods. In this regard I would focus on readability.There are things to consider though, e.g. sorting cannot be lazy (you have to look at all items before you can spit out the items in order) – that’s why you should always put your
Wherefilter before yourOrderByso you have less items to sort. This said I would restructure your code like this:Also note that I pulled out
searchError.Trim().ToLower()out of your lambda and assigned it to a variable once – otherwise this is executed every time the lambda is evaluated, which is really unnecessary work.Final edit: I also added a
ToList()to execute the query after your projection – otherwise your query really would be executed from your view which in general is bad for many reasons, e.g. you have to keep the database context alive for a potentially much longer time and you are violating separation of concerns – views should only be concerned about the view model but have nothing to do with acquiring the data.