0

This is my method :

public static IEnumerable<Answer> FilterByKeyValue(this IEnumerable<Answer> query, KeyFilterModel[] filters)
{
   if (filters != null && filters.Length > 0)
   {
      foreach (var filter in filters)
      {
         foreach (var value in filter.FilterValues)
           query = query.Where(f => f.RespondentEntryID.HasValue && f.RespondentEntry.Values.Any(g => g.Key.Name.Contains(filter.Key) && g.Values.Contains(value)));
      }

    }
    return query;
}

For each item in my iteration I have a query.Where( ... ) and that is a AND ... but I want to have this in an OR function.

Anyone that can help me?

  • 1
    What do you mean in an or function? How do you say that your function is an and function? – kelsier Nov 15 '14 at 09:38
  • i do not think I really understood your query but in case you need programmatic or then use || in place of &&, where ever you need, also you may want to group or (||) together and then apply && to the group or may be vice-versa – Mrinal Kamboj Nov 15 '14 at 09:41
  • 7
    @KenpachiZaraki: combining Where acts like "and", i.e. `Where(cond1).Where(cond2)` is equivalent to `Where(cond1 && cond2)`. OP is most likely looking for `Where(cond1 || cond2)`. – k.m Nov 15 '14 at 09:44
  • @jimmy_keen For that too OP needs to explain the exact requirement clearly where he needs || and where && – Mrinal Kamboj Nov 15 '14 at 10:09
  • You override `query` on each iteration. Maybe you should describe what you're actually trying to do. – Yuval Itzchakov Nov 15 '14 at 10:25
  • 4
    Check out: http://stackoverflow.com/questions/782339/how-to-dynamically-add-or-operator-to-where-clause-in-linq – Magnus Nov 15 '14 at 10:28
  • 1
    Agree with Magnus especially about the accepted answer of its link : use PredicateBuilder, it's simple and works very well. It's just have the little drawback to use an external library (not LINQ native feature) – AFract Nov 15 '14 at 11:11
  • I want to do this : Where(cond1 || cond2) in my function. My filter is a AND condition, because I always add a Where() statement for each item. I want for each item an OR statement. – Joeri Pansaerts Nov 15 '14 at 11:22
  • Couldn't you just merge the result lists of each single filter and than call distinct()? Allthough this might not be the most performant way. – Tobias Nov 15 '14 at 13:05
  • Although the question is tagged is tagged Expressions, it is not actually using Expressions or IQueryable so PredicateBuilder does not really apply to the question. – Andrew Radford Nov 16 '14 at 17:42

1 Answers1

1

To restate the problem: You are currently returning answers that meet ALL of the filters and you want to return answers that meet ANY of the filters.

Here is the code that will do that:

public static IEnumerable<Answer> FilterByKeyValue(this IEnumerable<Answer> query, KeyFilterModel[] filters)
{
    if (filters != null && filters.Length > 0)
    {
        query = query.Where(a => PassesAnyFilter(a, filters));
    }
    return query;
}

private static bool PassesAnyFilter(Answer answer, KeyFilterModel[] filters)
{
    foreach (var filter in filters)
        foreach (var value in filter.FilterValues)
        {
            if (answer.RespondentEntryID.HasValue && answer.RespondentEntry.Values.Any(g => g.Key.Name.Contains(filter.Key) && g.Values.Contains(value)))
            return true;
        }

    return false;
}
Andrew Radford
  • 3,227
  • 1
  • 20
  • 25