I want to create a dynamic linq expression for sql IN clause in EF 6.0 with the first code of the code. Please note that I am new to expressions. What I want to achieve
select * from Courses where CourseId in (1, 2, 3, 4) //CourseId is integer
A typical linq query looks like this. But I want to dynamically query it
string[] ids = new string[]{"1", "2", "3", "4"}; var courselist = DBEntities.Courses.Where(c => ids.Contains(SqlFunctions.StringConvert((decimal?)c.CourseId)))
There are two ways to make a dynamic expression.
1) one way is to go through identifiers and expressions.
The code below will generate the following expression in debug form
{f => ((StringConvert(Convert(f.CourseId)).Equals("23") Or StringConvert(Convert(f.CourseId)).Equals("2")) Or StringConvert(Convert(f.CourseId)).Equals("1"))}
Dynamic expression
var param = Expression.Parameters(typeof(Course), "f") MemberExpression property = Expression.PropertyOrField(param, "CourseId"); MethodInfo mi = null; MethodCallExpression mce = null; if (property.Type == typeof(int)) { var castProperty = Expression.Convert(property, typeof(double?)); var t = Expression.Parameter(typeof(SqlFunctions), "SqlFunctions"); mi = typeof(SqlFunctions).GetMethod("StringConvert", new Type[] { typeof(double?) }); mce = Expression.Call(null,mi, castProperty); } mi = typeof(string).GetMethod("Equals", new Type[]{ typeof(string)}); BinaryExpression bex = null; if (values.Length <= 1) { return Expression.Lambda<Func<T, bool>>(Expression.Call(mce, mi, Expression.Constant(values[0]), param)); }
2) The second method I tried (viewing debugging)
{f => val.Contains("23")} //val is parameter of values above
The dynamic expression above that I tried is
var param = Expression.Parameters(typeof(Course), "f") MemberExpression property = Expression.PropertyOrField(param, "CourseId"); var micontain = typeof(Enumerable).GetMethods().Where(m => m.Name == "Contains" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(string)); var mc = Expression.Call(micontain, Expression.Parameter(values.GetType(), "val"), Expression.Constant("2"));
I get the following errors:
- LINQ to Entities does not recognize the 'System.String StringConvert (System.Nullable`1 [System.Double])' method, and this method cannot be translated into the repository expression when I use the first methodology. I know that I can not use ToString with EF, so I used SqlFunctions, but it does not work for me.
- The 'val' parameter was not bound in the specified LINQ to Entities query expression using methodology 2
I have been trying this for the last 4 days. I searched for it, but did not find a suitable solution. Please help me.