1

I've got an Objectset that represents a set of people and I want to use it as the DataSource for a DataGridView control. But before that, I want to filter the set of people based on a search string. So if a search string were "David John" I would want to keep "David Johnson" and "John Davidson", but not "John Williams", "David Beckham" or "Al Green".

Here's what I've tried:

MyObjectContext context = GetContext();
string searchBox = "John David";
Regex regex = new Regex("[a-zA-Z]+", RegexOptions.Singleline);
MatchCollection matches = regex.Matches(searchBox);
IQueryable<Owner> q = ce.Owner;
foreach (Match match in matches)
{
    q = q.Where(o => o.FirstName.Contains(match.Value) 
        || o.LastName.Contains(match.Value));
}
findOwnerDataGrid.DataSource = q.OrderBy(o => o.LastName);

but it only seems to apply the last match "David".

How can I accomplish what I need to do? Any different or simpler solutions are welcome. If it matters, the grid is read-only so I don't have to worry about binding/editing considerations.

Michael J Swart
  • 3,060
  • 3
  • 29
  • 46
  • 1
    [I think you are hitting the issue here](http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach/8899347#8899347). I guess your original code would work if you assigned `match` to a local variable inside the `foreach` and referenced that in the lambda expression instead. – Martin Smith Mar 18 '13 at 07:41
  • Thanks for the insight Martin. It takes the mystery out of the bizarre behavior. – Michael J Swart Mar 18 '13 at 12:29

1 Answers1

3

I would use LINQ to Objects without regular expression.

var items = new List<string>() {
    "David Johnson", "John Davidson", "John Willians", "David Beckham", "Al Green"
};

var queryString = "David John";
var queryItems = queryString.Split(new char[] { ' ' });

var results = items.Where(x => queryItems.All(q => x.Contains(q))).ToList();

Returns what you want.

For your List<Owner> query would be probably like that:

var results = items.Where(x => queryItems.All(q => x.FirstName.Contains(q) ||
                                                   x.LastName.Contains(q)))
                   .ToList();
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263