I am trying to dynamically create the equivalent of the following Linq.
IQueryable<TypeOne> ones;
ones.Select(i => new TypeTwo { TwoProp = i.OneProp });
So far I have the following code but it isn't.
public class TypeOne
{
public string OneProp { get; set; }
}
public class TypeTwo
{
public string TwoProp { get; set; }
}
public static IQueryable<TypeTwo> Tester(IQueryable<TypeOne> data)
{
ConstructorInfo constructor = typeof(TypeTwo ).GetConstructor(new Type[] { });
Expression body = Expression.New(constructor);
ParameterExpression oneParam = Expression.Parameter(typeof(TypeOne), "one");
Expression prop1 = Expression.Property(oneParam, "OneProp");
ParameterExpression twoParam = Expression.Parameter(typeof(TypeTwo ), "two");
Expression prop2 = Expression.Property(twoParam, "TwoProp");
Expression assign = Expression.Assign(prop2, prop1);
body = Expression.Block(body, assign);
return data.Select(Expression.Lambda<Func<TypeOne, TypeTwo >>(body, oneParam));
}
However I get the following exception-:
Additional information: Expression of type 'System.String' cannot be used for return type 'TypeTwo'
You should use Expression.MemberInit for that, like this:
You can include as many
Expression.Bind
expressions (i.e. property assignments) as you want.