I have a lambda expression tree issue that I can’t figure out. I am trying to make a dynamic linq Select statement.
I have a dynamic repository created here:
private static dynamic GetRepository(Type type)
{
dynamic repository = typeof(IFactory).GetMethod("Create").MakeGenericMethod(typeof(IRepository<>).MakeGenericType(type)).Invoke(ObjectFactory.Instance, new object[] { });
return repository;
}
With this I need to call this only I don’t know x and SomeProperty at compile time. I have PropertyInfo propertyInfo with SomeProperty name and Type objectType with x type. It fails at Goal 1 with this exception:
System.Reflection.AmbiguousMatchException at GetMethod(string name)
The code:
private SomeObject CreateSomeObject (PropertyInfo propertyInfo, Type objectType)
{
var param = Expression.Parameter(objectType, "x");
MemberExpression expression = Expression.PropertyOrField(param, propertyInfo.Name);
//Goal 1: var selectExpression = Expression.Lambda<Func<objectType, object>>(expression, param);
var selectExpression = typeof(Expression).GetMethod("Lambda").MakeGenericMethod(typeof(Func<,>)
.MakeGenericType(objectType, typeof(object)))
.Invoke((object)null, new object[] { expression, param });
// Goal 2: List<object> list = GetRepository(objectType).FindAllQuery().Select(x => x.SomeProperty).ToList();
List<object> list = GetRepository(objectType).FindAll().Select(selectExpression);
}
How to solve this?
Update 1:
I have changed the way to select Lambda method, the way to pack 'param' parameter and I have added a object Converter to 'expression'.
private SomeObject CreateSomeObject (PropertyInfo propertyInfo, Type objectType)
{
var param = Expression.Parameter(objectType, "x");
Expression expression = Expression.Convert(Expression.PropertyOrField(param, propertyInfo.Name), typeof(object));
//Goal 1: var selectExpression = Expression.Lambda<Func<objectType, object>>(expression, param);
var selectExpression = typeof(Expression).GetMethods().First(m => m.Name == "Lambda" && m.IsGenericMethod)
.MakeGenericMethod(typeof(Func<,>)
.MakeGenericType(objectType, typeof(object)))
.Invoke((object)null, new object[] { expression, new [] { param }});
// Goal 2: List<object> list = GetRepository(objectType).FindAllQuery().Select(x => x.SomeProperty).ToList();
List<object> list = GetRepository(objectType).FindAll().Select(selectExpression);
}
But know I get this exception at Goal 2(Microsoft.CSharp.RuntimeBinder.RuntimeBinderException):
'System.Collections.Generic.List ' does not contain a definition for 'Select'
This is partly right because it is defined in System.Linq and it is an extension method. How do I get this working?