Freigeben über


You may get System.StackOverflowException in your asp.net application if your filter condition has too many "or" in your DataTable.Select function

 

In your application, if you add too many filter options with "or" condition in your datatable, you may get StackOverflowException exception in your application.

 

Queries:

In the DataTable.Select method the below queries are executed.

If you have a condition like below:
{name='winfin\App__3' OR name='winfin\X_Studentendag 2008' OR name='winfin\ScanFlowStore Gebruikers' OR name='winfin\CD BenC uitje 2008 Change' OR name='winfin\App_RHD' OR name='winfin\App_SmartDocuments_6.2_test' OR name='winfin\App_LogitechSetPoint' OR name='winfin\X_Foto''s Renovatie' OR name='winfin\App_ODF_TEST' OR name='winfin\AG_HOMESERVER_FINP51' OR name='winfin\DGRB RR (hoofdstructuur)' OR name='winfin\Xtender Email B' }

 

 

Basically it looks like filter condition is causing stack overflow exception here. Huge filter condition can result in StackOverflowException since binary operations are evaluated recursively.

 

There are three options here solve this issue.:

1. Modify the expression to use the IN operator instead of chaining multiple terms together with the OR operator.
For example, do not use ID=1 OR ID=2 OR ID=3, use ID IN(1,2,3) to replace.
2. Modify the expression to use parentheses around groups of terms. This will result in intermediate values being generated and less recursion.
For example, use (ID=1 OR ID=2 OR ID=3 ...) OR (ID=11 OR ID=12 ...) ...
3. Select just the records you want to display instead of filtering them locally.

 

 

So as a workaround we should change your filter builder to produce a code like below (using parenthesis)

(name='winfin\App_FireFox_3' OR name='winfin\BEB_IO_IBO' OR name='winfin\App_TimeTell_RAD') OR (name='winfin\X_Studentendag 2008' OR name='winfin\CD BenC DenI Aanbestedingen 2008' OR name='winfin\ScanFlowStore Gebruikers')

Another way is we may  the expression to use the IN operator instead of chaining multiple terms together with the OR operator.

 

DataTable dtGroupUsers = new DataTable("GroupUsers");

            DataColumn col1 = new DataColumn("col1", System.Type.GetType("System.String"));

            dtGroupUsers.Columns.Add(col1);

            String[] myArr = new String[] { "RED", "RED", "RED", "test", "green", "green", "green", "indigo", "indigo", "indigo" };

            DataRow row;

            for (int i = 0; i < 10; i++)

            {

                row = dtGroupUsers.NewRow();

                row["col1"] = myArr[i] ;

                // Be sure to add the new row to the

                // DataRowCollection.

                dtGroupUsers.Rows.Add(row);

            }

            StringBuilder sbFilter = new StringBuilder();

            StringCollection groupnames=new StringCollection();

            String[] myArr2 = new String[] { "RED", "orange", "yellow", "RED", "green", "blue", "RED", "indigo", "violet", "RED" };

            groupnames.AddRange(myArr2);

            sbFilter.Append(" col1 in (");

            foreach (string s in groupnames)

            {

                sbFilter.Append("'"+s+"',");

            }

            sbFilter.Append(")");

            sbFilter.Remove(sbFilter.ToString().LastIndexOf(','), 1);

            DataRow[] drs;

            drs = dtGroupUsers.Select(sbFilter.ToString());

 

Please let me know if you have any questions.

 

Many Thanks

Kagan Arca