6 ms·
Here's an example in C#. Imagine you're querying a database of products (here represented by integers). Users can enter filter parameters - you want to build yo
by rikkus 12y ago
Here's an example in C#. Imagine you're querying a database of products (here represented by integers). Users can enter filter parameters - you want to build your query dynamically based upon what they enter. With LINQ, you can do this kind of composing with no effort. You also get to run the same code on any kind of Queryable, so if you feel like doing some of the work in RAM and some using a DB, your query is usually going to be very similar, if not the same.
Yes, you still have to understand what you're querying against and how you should build your queries to make best use, but I'd much rather write this kind of code than try to concatenate SQL.
IQueryable<int> Source()
{
return Enumerable.Range(0, int.MaxValue).AsQueryable();
}
class UserFilter
{
public bool? EvensOnly { get; set; }
public int? Minimum { get; set; }
public int? Maximum { get; set; }
}
IEnumerable<int> Search(IQueryable<int> source, int currentPage, int pageSize, UserFilter filter)
{
var result = source;
if (filter.EvensOnly.HasValue && filter.EvensOnly.Value)
{
result = result.Where(i => i % 2 == 0);
}
if (filter.Minimum.HasValue)
{
result = result.Where(i => i >= filter.Minimum.Value);
}
if (filter.Maximum.HasValue)
{
result = result.Where(i => i <= filter.Maximum.Value);
}
return result.Skip(currentPage * pageSize).Take(pageSize);
}
void Main()
{
var currentPage = 4;
var pageSize = 5;
var filter = new UserFilter {
EvensOnly = true,
Minimum = 1000
};
var searchResults = Search(Source(), currentPage, pageSize, filter);
}
- zaroth 12y agoFYI, you can also write it this way, although you may find it less readable, it emits the exactly same query to the DB, and I personally find it much more pleasing; IEnumerable<int> Search(...) { return result .Where(i => !f.EvensOnly || i % 2 == 0) .Where(i => !f.Minimum.HasValue || i >= f.Minimum) .Where(i => !f.Maximum.HasValue || i <= f.Maximum) .Skip(currentPage * pageSize).Take(pageSize); } Nit: EvensOnly should not be nullable since it has only two states.
- rikkus 12y agoI find this more readable. In fact, the code here looks more like this: .FilterByEvensOnly() .FilterByMinimum() .FilterByMaximum() Obviously the example is trivialised and the real filters are more complex, requiring joins, but the pattern gives a very readable way of writing an efficient query. Unfortunately EF produces an unreadable query when there are a few dozen filters, but the LINQ code is readable, so there hasn't been any difficulty debugging.
- bmurphy1976 12y agoWorks great until you need some feature that is only implemented in SQL and in my experience that's unfortunately about 30% of the time.