简体   繁体   中英

Avoid to browse a list multiple time with linq, with dynamic conditions (filter)

I have a list with Article objects. Parameters for this object are

Category, Description, Status, Class

The user can filter the list with the combinaison he wants. Only Description, or Category + Class, an so on.

So if the user choose a criterion i'll get an int >= 0, otherwise i'll get -1.

For example if he choose to filter with Status and Category , i'll get

FilterCategory = x, FilterDescription = -1, FilterStatus = y, FilterClass = -1

My way to filter the list is the following:

if (FilterCategory != -1)
    list = list.Where(a => a.Category == FilterCategory);
if (FilterDescription != -1)
    list = list.Where(a => a.Description == FilterDescription);
if (FilterStatus != -1)
    list = list.Where(a => a.Status == FilterStatus);
if (FilterClass != -1)
    list = list.Where(a => a.Class == FilterClass);

In this way, i have to iterate the list 4 time, it's not efficient with a lot of items. I would browse the list once, and check the 4 condition in an unique where. But i don't know how to do that with the specific condition != -1.

Thank you

As Juharr mentions in the comments, Linq will not evaluate your .Where right after calling it. Only when calling ToList/ToArray/First/Single/foreach will it evaluate the clause and it will automatically combine your filters.

You can do a HUGE Where query moving all your conditions it a single Where by noticing that:

if (FilterCategory != -1)
    list = list.Where(a => a.Category == FilterCategory);

is equivalent to:

list = list.Where(a => FilterCategory == -1 || a.Category == FilterCategory);

Then the query is:

list = list.Where(a => (FilterCategory == -1 || a.Category == FilterCategory)
                    && (FilterDescription == -1 || a.Description == FilterDescription)
                    && (FilterStatus == -1 || a.Status == FilterStatus)
                    && (FilterClass == -1 || a.Class == FilterClass));

But I really doubt it will improve your enumeration performance.

list = list.Where(a => (FilterCategory != -1 || a.Category == FilterCategory) && 
                                       (FilterDescription != -1 || a.Description == FilterDescription) &&
                                       (FilterStatus != -1 || a.Status == FilterStatus) &&
                                       (FilterClass != -1 || a.Class == FilterClass));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM