S
Scott
In a Silverlight 2.0 application, I am attempting to filter a list of objects
using LINQ. The custom object named Incident has a property named “DOW†that
is of the type of DayOfWeek. The use case is that the user can select a
number of days of week and then the list of incidents is to be filtered. For
example, the user may select “Monday†and “Tuesdayâ€, the resulting list is to
only contain objects that have the DOW property of Monday and Tuesday.
I have been successful in selecting objects when there are a known number of
parameters, such as one day of the week; the challenge has to make this
dynamic. I have attempted to use the PredicateBuilder class but there is a
compile error when the List<>.Where used
Error 1 The type arguments for method
'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>,
System.Func<TSource,int,bool>)' cannot be inferred from the usage. Try
specifying the type arguments explicitly. C:\
Test_Linq\Test_Linq\Page.xaml.cs 57 43 Test_Linq
Outlined below is the sample code.
public class Incident
{
public string FirstName;
public string LastName;
public DayOfWeek DOW;
public int TimeOfDay;
public int IncidentType;
}
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f =>
true; }
public static Expression<Func<T, bool>> False<T>() { return f =>
false; }
public static Expression<Func<T, bool>> Or<T>(this
Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2,
expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr),
expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this
Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2,
expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr),
expr1.Parameters);
}
}
//- Code to filter the list of incidents
List<Incident> incidents = new List<Incident>();
incidents.Add(new Incident() {FirstName= "s", LastName="m", DOW =
DayOfWeek.Friday});
incidents.Add(new Incident() {FirstName= "j", LastName="l", DOW=
DayOfWeek.Friday});
incidents.Add(new Incident() { FirstName = "Kim", LastName = "m", DOW =
DayOfWeek.Monday });
incidents.Add(new Incident() { FirstName = "x", LastName = "1", DOW =
DayOfWeek.Thursday });
incidents.Add(new Incident() { FirstName = "x", LastName = "2", DOW =
DayOfWeek.Tuesday });
List<DayOfWeek> listDayOfWeek = new List<DayOfWeek>();
listDayOfWeek.Add(DayOfWeek.Friday);
listDayOfWeek.Add(DayOfWeek.Monday);
var predictate = PredicateBuilder.False<Incident>();
foreach (DayOfWeek day in listDayOfWeek)
{
DayOfWeek queryDay = day;
predictate = predictate.Or(p => p.DOW == queryDay);
}
//Line that cannot compile
IQueryable<Incident> result = incidents.Where(predictate);
using LINQ. The custom object named Incident has a property named “DOW†that
is of the type of DayOfWeek. The use case is that the user can select a
number of days of week and then the list of incidents is to be filtered. For
example, the user may select “Monday†and “Tuesdayâ€, the resulting list is to
only contain objects that have the DOW property of Monday and Tuesday.
I have been successful in selecting objects when there are a known number of
parameters, such as one day of the week; the challenge has to make this
dynamic. I have attempted to use the PredicateBuilder class but there is a
compile error when the List<>.Where used
Error 1 The type arguments for method
'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>,
System.Func<TSource,int,bool>)' cannot be inferred from the usage. Try
specifying the type arguments explicitly. C:\
Test_Linq\Test_Linq\Page.xaml.cs 57 43 Test_Linq
Outlined below is the sample code.
public class Incident
{
public string FirstName;
public string LastName;
public DayOfWeek DOW;
public int TimeOfDay;
public int IncidentType;
}
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T>() { return f =>
true; }
public static Expression<Func<T, bool>> False<T>() { return f =>
false; }
public static Expression<Func<T, bool>> Or<T>(this
Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2,
expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse(expr1.Body, invokedExpr),
expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this
Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke(expr2,
expr1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso(expr1.Body, invokedExpr),
expr1.Parameters);
}
}
//- Code to filter the list of incidents
List<Incident> incidents = new List<Incident>();
incidents.Add(new Incident() {FirstName= "s", LastName="m", DOW =
DayOfWeek.Friday});
incidents.Add(new Incident() {FirstName= "j", LastName="l", DOW=
DayOfWeek.Friday});
incidents.Add(new Incident() { FirstName = "Kim", LastName = "m", DOW =
DayOfWeek.Monday });
incidents.Add(new Incident() { FirstName = "x", LastName = "1", DOW =
DayOfWeek.Thursday });
incidents.Add(new Incident() { FirstName = "x", LastName = "2", DOW =
DayOfWeek.Tuesday });
List<DayOfWeek> listDayOfWeek = new List<DayOfWeek>();
listDayOfWeek.Add(DayOfWeek.Friday);
listDayOfWeek.Add(DayOfWeek.Monday);
var predictate = PredicateBuilder.False<Incident>();
foreach (DayOfWeek day in listDayOfWeek)
{
DayOfWeek queryDay = day;
predictate = predictate.Or(p => p.DOW == queryDay);
}
//Line that cannot compile
IQueryable<Incident> result = incidents.Where(predictate);