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

  1. Open a new console application in Visual Studio. Name it PredicateFilters.

  2. 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.

  3. Comment out the Main method in StudentClass.

  4. Replace class Program with the following code.

    // To run this sample, first specify some integer values for the command line. 
    // The numbers 111 through 122 are all valid student IDs. 
    // In Visual Studio or C# Express, click on Project > Properties > Debug. 
    // Call the method: QueryByID(args); 
    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);
        }
    }
    /* 
     Output (depends on args):
       111 114 118
    
       Garcia: 114
       Garcia: 118
       Omelchenko: 111
    */
    
  5. Add the following line to the Main method in class DynamicPredicates, under the declaration of ids.

    QueryById(ids);
    
  6. Press F5 to run the project.

  7. The following output is displayed in a Command Prompt window:

    Garcia: 114

    O'Donnell: 112

    Omelchenko: 111

  8. 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.

  9. Click the Debug tab.

  10. 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.

  11. Change QueryByID(ids) to QueryByID(args) in the Main method.

  12. Press F5 to run the project.

  13. 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

  1. 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.

  2. 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. In Visual Studio or C# Express, click on Project > Properties > Debug to specify 
    // command line arguments. 
    // 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);
        }
    }
    
  3. In the Command line arguments window, replace the ID numbers from the previous procedure with an integer value between 1 and 4.

  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]).

  5. 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.

See Also

Concepts

LINQ Query Expressions (C# Programming Guide)

Reference

where clause (C# Reference)

Change History

Date

History

Reason

July 2009

Clarified the procedures to follow to run the examples.

Customer feedback.