I have been writing expression tree for creating lambda expressions dynamically.
To start it up small, I am reading data from a JSON file into an Class object. And trying to build the where condition on two conditions.
string jsonnew = File.ReadAllText(@"C:\Users\nested_Json.txt");
var rootObject1 = JsonConvert.DeserializeObject<Citizen>(jsonnew);
IEnumerable<Citizen> enumerable = new[] { rootObject1 };
IQueryable<Citizen> queryableDataaa = enumerable.AsQueryable();
ParameterExpression pe1 = Expression.Parameter(typeof(string), "rootobject");
PropertyInfo field = typeof(Citizen).GetProperty("name");
PropertyInfo field2 = typeof(Citizen).GetProperty("id");
ParameterExpression targetExp = Expression.Parameter(typeof(Citizen), "rootobject");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "\"StrozeR\"");
ParameterExpression valueExp2 = Expression.Parameter(typeof(Int32),"1765116");
MemberExpression fieldExp = Expression.Property(targetExp, field);
MemberExpression fieldExp2 = Expression.Property(targetExp, field2);
Expression assignExp = Expression.Equal(fieldExp, valueExp);
Expression assignExp2 = Expression.Equal(fieldExp2, valueExp2);
Expression predicateBody1 = Expression.AndAlso(assignExp, assignExp2);
MethodCallExpression whereCallExpression1 = Expression.Call(
typeof(Queryable),
"where",
new Type[] { queryableDataaa.ElementType},
queryableDataaa.Expression,
Expression.Lambda<Func<string, bool>>(predicateBody1, new ParameterExpression[] { pe1 }));
Can anyone help me out in understand why I am getting
No generic method 'where' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. error
You must
Citizen
for the whole where clause expressionWhere
(with capital w) method of IQueryable
where is an extension method defined in System.Linq.Queryable
, then provide it's generic typehere is the corrected code:
var targetExp = Expression.Parameter(typeof(Citizen), "rootobject");
var valueExp = Expression.Constant("\"StrozeR\"");
var valueExp2 = Expression.Constant(1765116);
var fieldExp = Expression.Property(targetExp, "name");
var fieldExp2 = Expression.Property(targetExp, "id");
var assignExp = Expression.Equal(fieldExp, valueExp);
var assignExp2 = Expression.Equal(fieldExp2, valueExp2);
var predicateBody1 = Expression.AndAlso(assignExp, assignExp2);
var queryableType = typeof(System.Linq.Queryable);
var whereMethod = queryableType.GetMethods()
.First(m =>
{
var parameters = m.GetParameters().ToList();
//Put more restriction here to ensure selecting the right overload
//the first overload that has 2 parameters
return m.Name == "Where" && m.IsGenericMethodDefinition &&
parameters.Count == 2;
});
var whereClause = Expression.Lambda<Func<Citizen, bool>>(predicateBody1,
new ParameterExpression[] { targetExp });
var genericMethod = whereMethod.MakeGenericMethod(typeof(Citizen));
var newQuery = (IQueryable<Citizen>)genericMethod
.Invoke(genericMethod, new object[] { queryableDataaa, whereClause });