How to: Dynamically Specify Predicate Filters at Runtime (C# Programming Guide)
In some cases you do not know until run time how many predicates you have to apply to source elements in the where clause. One way to dynamically specify multiple predicate filters is to use the Contains method, as shown in the following example. The example is constructed in two ways. First, the project is run by filtering on values that are provided in the program. Then the project is run again by using input provided at run time.
To filter by using the Contains method
Open a new console application in Visual Studio. Name it PredicateFilters.
Copy the StudentClass class from How to: Query a Collection of Objects (C# Programming Guide) and paste it into namespace PredicateFilters underneath class Program. StudentClass provides a list of Student objects.
Comment out the Main method in StudentClass.
Replace class Program with the following code.
class DynamicPredicates : StudentClass { static void Main(string[] args) { string[] ids = { "111", "114", "112" }; Console.WriteLine("Press any key to exit."); Console.ReadKey(); } static void QueryByID(string[] ids) { var queryNames = from student in students let i = student.ID.ToString() where ids.Contains(i) select new { student.LastName, student.ID }; foreach (var name in queryNames) { Console.WriteLine("{0}: {1}", name.LastName, name.ID); } } }
Add the following line to the Main method in class DynamicPredicates, under the declaration of ids.
QueryById(ids);
Press F5 to run the project.
The following output is displayed in a Command Prompt window:
Garcia: 114
O'Donnell: 112
Omelchenko: 111
The next step is to run the project again, this time by using input entered at run time instead of array ids. In Solution Explorer, right-click PredicateFilters and then click Properties.
Click the Debug tab.
In the Command line arguments window, type 122, 117, 120, and 115, separated by spaces: 122 117 120 115. When the project is run, those values become elements of args, the parameter of the Main method.
Change QueryByID(ids) to QueryByID(args) in the Main method.
Press F5 to run the project.
The following output is displayed in a Command Prompt window:
Adams: 120
Feng: 117
Garcia: 115
Tucker: 122
To filter by using a switch statement
You can use a switch statement to select among predetermined alternative queries. In the following example, studentQuery uses a different where clause depending on which grade level, or year, is specified at run time.
Copy the following method and paste it into class DynamicPredicates.
// To run this sample, first specify an integer value of 1 to 4 for the command // line. This number will be converted to a GradeLevel value that specifies which // set of students to query. // Call the method: QueryByYear(args[0]); static void QueryByYear(string level) { GradeLevel year = (GradeLevel)Convert.ToInt32(level); IEnumerable<Student> studentQuery = null; switch (year) { case GradeLevel.FirstYear: studentQuery = from student in students where student.Year == GradeLevel.FirstYear select student; break; case GradeLevel.SecondYear: studentQuery = from student in students where student.Year == GradeLevel.SecondYear select student; break; case GradeLevel.ThirdYear: studentQuery = from student in students where student.Year == GradeLevel.ThirdYear select student; break; case GradeLevel.FourthYear: studentQuery = from student in students where student.Year == GradeLevel.FourthYear select student; break; default: break; } Console.WriteLine("The following students are at level {0}", year.ToString()); foreach (Student name in studentQuery) { Console.WriteLine("{0}: {1}", name.LastName, name.ID); } }
In the Command line arguments window, replace the ID numbers from the previous procedure with an integer value between 1 and 4.
In the Main method, replace the call to QueryByID with the following call, which sends the first element from the args array as its argument: QueryByYear(args[0]).
Press F5 to run the project.
To use this method in your own applications
- When you adapt this method to your own application, remember that LINQ requires version 3.5 or 4 of the .NET Framework, and that the project must contain a reference to System.Core.dll and a using directive for System.Linq. LINQ to SQL, LINQ to XML, and LINQ to DataSet types require additional using directives and references. For more information, see How to: Create a LINQ Project.