views:

55

answers:

1

Hi,

Scenario: I have a list and three search filters. Something like:

ResultList = OriginalList.Where(filter1).Where(filter2).Where(filter3);


Question: Can I update filter 3, and then have the ResultList update, without having LINQ running filter1 and filter2? (I want to improve performance)

Basically, it would be the same as:

Result1 = OriginalList.Where(filter1).Where(filter2);
Result2 = Result1.Where(filter3);
UpdateFilter3(); // Just changes the filter somehow
Result2 = Result1.Where(filter3);
return Result2;

This just is a little cumbersome to keep track of, and I was wondering if there is a smarter way to do this? I looked at Continuous LINQ (CLINQ: http://clinq.codeplex.com/), however, it seems that it just basically tells the LINQ to refresh the whole WHERE statement everytime just one of the filters change.

Any words of wisdom are greatly appreciated :)

Thanks,
Michael

+1  A: 

(Assumption: you used a variable name OriginalList rather than OriginalQuery or something like that, so I assume we're talking about straight LINQ-To-Object and IEnumerable here.)

Yes you can, by making Result1 a List rather than IEnumerable. Like this:

Result1 = OriginalList.Where(filter1).Where(filter2).ToList();
Result2 = Result1.Where(filter3);
UpdateFilter3(); // Just changes the filter somehow
Result2 = Result1.Where(filter3);
return Result2;

As a List, Result1 isn't just an IEnumerable waiting to go, but an actual solid list of stuff, with filter1 and filter2 permanently applied, so to speak. When line 4 executes above, it will still be off of the solid List that you created on line 1. You could swap out filter 3 and reapply to Result1 a hundred times, and filter1 and filter2 will still only have been applied once.

There is a cost to creating the list, but this will be more than made up for when reapplying multiple filter3 filters, especially if filter1 and filter2 are complicated or substantially reduce the set.

Patrick Karcher
And if you save off Result1 somewhere so you can reuse it, then filter3 would be *all* you needed to apply.
GalacticCowboy
Thanks!I should have explained a little further: I would like to also be able to change filter1 and filter2 :)I have looked more closely at CLINQ, and I believe it may be possible to use it in a similar way that you just described.The upside of CLINQ, is that it can then reevaluate just a single filter at a time (say update filter1) and then only the items that are added/removed via filter1 are then re-evaluated by filter2 and subsequently filter3.This should reduce the memory and cpu load significantly. I need to confirm this with the developer of CLINQ though first. I'll update you asap
Bodekaer
CLINQ sounds like what you want. It is likely to make your code simpler. I don't think it will increase performance though. To do that you'll have to have a plan yourself and be clever. That could be tricky. You might need cached intermediate lists, or try to predict what the user might toggle next, that sort of thing. Good Luck.
Patrick Karcher
Bindable LINQ turned out to be perfect! (similar to CLINQ, however also supports INotify on filter parameters).It does indeed decrease performance slightly at first, however in the long run performance is grealty improved, as I will not have to reload the filters on the entire lists, but only for those items that are added.Also removed items from the main list automatically gets removed in Result1 and Result2, so that's just perfect :)Thanks for the input everyone.
Bodekaer