0

I'm using Mock Data for prototyping something. I want to simulate a search on different fields. Not all search parameters must be filled. I would like to filter my Mock Data with the set filters, but I can't seem to make it work.

This is what I have: A list of modules with some properties. like ID, Name Code, etc.

var AllModules = new List<Module>{
  new Module{Id=1, Name="MockName", Code="ModCode", Active:false},
  new Module{Id=2, Name="MockNameFoo", Code="ModCodeFoo", Active:true}
 }

Then I would like to add where clauses depending on the filters properties.

class Filter{
    string Text {get;set;}
    bool? IsActive {get;set;}
}

then I would like to filter the list depending if the filters are set or not, so I have tried:

public <List<Module> GetModules(Filter modulesQuery)
{

  var query = from module in AllModules.AsQueryable()
                        select module;
  if (modulesQuery.IsActive.HasValue)
  {
    query.Where(x => x.Active== modulesQuery.IsActive.value);
  }
  if (!string.IsNullOrEmpty(modulesQuery.Text))
  {
    query.Where(x => x.Name.Contains(modulesQuery.Text,StringComparison.CurrentCultureIgnoreCase)||
        x.Code.Contains(modulesQuery.Text, StringComparison.CurrentCultureIgnoreCase)));
  }
 return query.ToList();
}

This is however not working and always returns me the complete list. It ignores all the where clauses, event thou I see that it goes to each if statements and "adds" them.

I don't know if this is completely wrong? I had the same thing when I first had the code with predicate Builder. BTW this is a .netCore project... but I don't think that make a difference here.

Thank you

Its_707_not_LOL
  • 13
  • 1
  • 2
  • 7
CodeHacker
  • 2,127
  • 1
  • 22
  • 35

3 Answers3

1

You need to assign the query in your if blocks back to the local variable. LINQ doesn't mutate the original query, but "adds" to it. As you're not assigning it, the return value from the Where() calls doesn't end up being used.

public List<Module> GetModules(Filter modulesQuery)
{

  var query = from module in AllModules.AsQueryable()
                        select module;
  if (modulesQuery.IsActive.HasValue)
  {
    query = query.Where(x => x.Active== modulesQuery.IsActive.value);
  }

  if (!string.IsNullOrEmpty(modulesQuery.Text))
  {
    query = query.Where(x => x.Name.Contains(modulesQuery.Text,StringComparison.CurrentCultureIgnoreCase)||
        x.Code.Contains(modulesQuery.Text, StringComparison.CurrentCultureIgnoreCase)));
  }

  return query.ToList();
}
Martin Costello
  • 9,672
  • 5
  • 60
  • 72
1

Try assigning the result back to the query variable.

I don't know the rest of the implementation, but I would recommend that you leave it as an IQueryable. So you're able to manipulate it more without persisting it at this stage.

Only use a ToList/ToArray when you really need to.

public IQueryable<Module> GetModules(Filter modulesQuery)
{

    var query = from module in AllModules.AsQueryable()
                        select module;

    if (modulesQuery.IsActive.HasValue)
    {
        query = query.Where(x => x.Active== modulesQuery.IsActive.value);
    }
    if (!string.IsNullOrEmpty(modulesQuery.Text))
    {
        query = query.Where(x => x.Name.Contains(modulesQuery.Text,StringComparison.CurrentCultureIgnoreCase)||
        x.Code.Contains(modulesQuery.Text, StringComparison.CurrentCultureIgnoreCase)));
    }
    return query;
}
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
0

Where returns an IEnumerable of the values you've filtered on. It does not mutate your original collection.

Example:

var filteredList = query.Where(x => x.Active== modulesQuery.IsActive.value);

Right now, you're just ignoring the return value from Where, which I feel like should be a compiler warning but whatever.

WBuck
  • 5,162
  • 2
  • 25
  • 36