1
if (i == 1) //if dropdown #1 index > 0
{
    strSelectedType = ViewState["EN"].ToString();
    strSelectedCol = "Name";
}
if (i == 2) //if dropdown #2 index > 0
{
    strSelectedType = ViewState["SU"].ToString();
    strSelectedCol = "Super";
}
if (i == 3) //if dropdown #3 index > 0
{
    strSelectedType = ViewState["DT"].ToString();
    strSelectedCol = "Deran";
}
if (i == 4) //if dropdown #4 index > 0
{
    strSelectedType = ViewState["PR"].ToString();
    strSelectedCol = "PRate";
}
DataTable dtTest = new DataTable();
dtTest = (DataTable)ViewState["gvDataTable"];

DataTable selectedTable = dtTest.AsEnumerable()
              .Where(r => r.Field<string>(strSelectedCol) == strSelectedType)
              .CopyToDataTable();

The above code is only using one column to filter.

How can I modify the dtText.AsEnumerable() so that it will filter like this:

DataTable selectedTable = dtTest.AsEnumerable()
          .Where(if (dropdown #1 > 0) {r => r.Field<string>(strSelectedCol) == strSelectedType }
                if (dropdown #2 > 0) { r => r.Field<string>(strSelectedCol) == strSelectedType }
                if (dropdown #3 > 0) { r => r.Field<string>(strSelectedCol) == strSelectedType }
                if (dropdown #4 > 0) { r => r.Field<string>(strSelectedCol) == strSelectedType })
          .CopyToDataTable();

It will iterate through each dropdown append filter if the selected index > 0.

2
  • In your code i cannot be equal to two different values at same time. What is condition for filtering by several columns? Commented Feb 19, 2016 at 14:03
  • The first code section is when I was selecting one column to filter. I would like to change it so it can use one or more columns to filter. Commented Feb 19, 2016 at 14:05

4 Answers 4

4

There are some simplications can be made for your case, for instance prepare this first:

List<string> a = new List<string>() {"EN", "SU", "DT", "PR"};
List<string> b = new List<string>() {"Name", "Super", "Deran", "PRate"};

Then you could simply do:

strSelectedType = ViewState[a[i-1]].ToString();
strSelectedCol = b[i-1];    

Then if you have list of dropdown, you could also do

var query = dtTest.AsEnumerable();

for (int i = 0; i < 4; ++i)
  if (dropdown #i-1 index > 0) {
    query = query.Where(r => r.Field<string>(strSelectedCol) == ViewState[strSelectedType].ToString());
    var result = query.CopyToDataTable();
    //Do something, your DataTable is here
  }

You could use List<KeyValuePair> too:

List<KeyValuePair<string,string>> lkvp = new List<KeyValuePair<string,string>>(){
    new KeyValuePair("EN", "Name"),
    new KeyValuePair("SU", "Super"),
    new KeyValuePair("DT", "Deran"),
    new KeyValuePair("PR", "PRate")
}

And use it like this

strSelectedType = ViewState[lkvp[i-1].Key].ToString();
strSelectedCol = lkvp[i-1].Value;    
Sign up to request clarification or add additional context in comments.

14 Comments

Thumb up, but maybe change two list declaring to one DIctionary?
@progpow ah yes! that is certainly an alternative since we only need to you key and value
sorry to Tuple :) We also use third type for Index Tuple<int,string,string>
@progpow the index is still needed. List of KVP or Tuple may also be an option.
@SiKni8 sorry, it seems like the fault could be mine for not understanding your question. At first, because I see your if (i == 1) if(i == 2) etc, I thought that you may only have one i value at a time, but if you need the strSelectedType/strSelectedCol to be dynamically changed, then you could put them in the for loop too. However, I cannot infer much from the question what is the exact case. A more info would be helpful
|
3

Use a predicate builder.

It helps especially when you don't know the exact options to filter. You simple build your predicate before you get to the point of filtering.

it improves performs of you application because you won't need to filter your collection more than once.

Read the link below: http://www.albahari.com/nutshell/predicatebuilder.aspx

6 Comments

PredicateBuilder for simple filtering? Overkill
One word says it all: overkill.
Its best you explain how it is overkill to let us know.
@ZiregbeOtee add some real code and you'll see. Currently it's link-only answer
@SergeyBerezovskiy Question for you, since you are using only = how will it use for more than one dropdownlist? You aren't using +=
|
2

You can build up query step by step. Just conditionally add new filters and assign result to original query variable:

var query = dtTest.AsEnumerable();

if (dropdown1.SelectedIndex > 0)
    query = query.Where(r => r.Field<string>("Name") == ViewState["EN"].ToString());

if (dropdown2.SelectedIndex > 0)
    query = query.Where(r => r.Field<string>("Super") == ViewState["SU"].ToString());

// etc

DataTable selectedTable = query.CopyToDataTable();

If you can change ViewState keys so that they'll match dropdowns ids (or vise versa), then you can easily build a list of filters and then apply them all in a loop:

var columns = new Dictionary<string, string> {
    ["EN"] = "Name",
    ["SU"] = "Super",
    ["DT"] = "Deran",
    ["PR"] = "PRate"
};

var filters = from ddl in Controls.OfType<DropDownList>()
              where ddl.SelectedIndex > 0 && columns.ContainsKey(ddl.ID)
              select new {
                  Column = columns[ddl.ID], 
                  Value = ViewState[ddl.ID].ToString()
              };

var query = dtTest.AsEnumerable();
foreach(var fitler in filters)
   query = query.Where(r => r.Field<string>(fitler.Column) == fitler.Value);

DataTable selectedTable = query.CopyToDataTable();

9 Comments

That is what I was looking for. Thank you.
Since we are only using =, what if more than one dropdownlist has a index of > 0?
@SiKni8 it's not clear how you are using dropdownlists. In your question there is some pseudo-code for checking this conditions. Also as you can see I use different dropdowns to build query
The first code section in my question was only for one column filtering. In your code for example, you are using query = and then query = . Doesn't the second query= overwrite the first one?
@SiKni8 second query overwrites what is stored in query. But you are missing that second query is modified first query: query = Something(query). Thus you are keep modifying original query and storing last modifications in original variable
|
1

Where calls can be chained:

var rows = dtTest.AsEnumerable();

if (...)
    rows = rows.Where(r => ...);

if (...)
    rows = rows.Where(r => ...);

...

var result = rows.CopyToDataTable();

Alternatively, if you want to store the conditions for later use, you can do that as well:

var conditions = new List<Func<DataRow, bool>>();

if (...)
    conditions.Add(r => ...);

if (...)
    conditions.Add(r => ...);

...

var query = dtTest.AsEnumerable();
foreach (var cond in conditions)
    query = query.Where(cond);

var result = query.CopyToDataTable();

2 Comments

Although it is using row = ... if more than one ddl i selected it will use for all?
@SiKni8: I am sorry, I don't understand your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.