Reputation: 6878
I have a combobox and a Textbox. I can select a column in the combobox and then search for the thing.
So if I select "country" and type in the Textbox "Netherlands" (or a part of it) It should bring up all the customers that live in The Netherlands.
However, this does not work.
I have the country now hardcoded but how do I made that dynamic, so it's what I selected in the combobox?
This is my code:
CustomerContext context = new CustomerContext();
IQueryable<customer> customers = from x in context.customers
where x.country.Contains(SearchBox.Text)
select x;
Upvotes: 0
Views: 53
Reputation: 52290
Brute force/straightforward:
IQueryable<customer> customers = from x in context.customers
where (ComboBox.SelectedValue == "Country") && x.country.Contains(SearchBox.Text)
|| (ComboBox.SelectedValue == "City") && x.city.Contains(SearchBox.City)
|| (ComboBox.SelectedValue == "State") && x.state.Contains(SearchBox.State)
select x;
There is absolutely nothing wrong with the above solution, but a lot of engineers will pooh pooh it because it doesn't seem maintainable or elegant or whatever. Harumph.
Fancy/elegant (a.k.a. complicated):
Note: You must arrange the items in the ComboBox in an order that matches the searches
array.
static private readonly Func<customer, string>[] _searches;
static private Class() //Static constructor
{
_searches = new Func<customer,string>[]
{
(c) => customer.City,
(c) => customer.State,
(c) => customer.Country
}
}
protected virtual void DoSearch() //Handles the search event
{
var search = _searches[ComboBox.SelectedIndex];
IQueryable<customer> customers = from x in context.customers
where search(x).Contains(SearchBox.Text)
select x;
}
The idea here is that you set up a series of lambdas in an array. Each lambda accepts a customer as input and returns one of the properties.
When the user triggers a search, you use the ordinal position in the combo box to choose a lambda expression corresponding to the property to be searched. You then use the lambda expression in your LINQ, causing the WHERE expression to search the property chosen by the lambda.
Using a dictionary
If you don't like the dependency between the array and the ordering of the combo box, you can use a dictionary instead:
static private readonly Dictionary<string, Func<customer, string>> _searches;
static private Class() //Static constructor
{
_searches = new Dictionary<string, Func<customer,string>>();
_searches.Add("City", (c) => customer.City);
_searches.Add("State", (c) => customer.State);
_searches.Add("Country", (c) => customer.Country);
}
protected virtual void DoSearch() //Handles the search event
{
var search = _searches[ComboBox.SelectedValue];
IQueryable<customer> customers = from x in context.customers
where search(x).Contains(SearchBox.Text)
select x;
}
Upvotes: 2