But this time the projection that I had to create had so many possibilities that building it using if then else approach means a lot of ugly code. So I decided to create it dynamically without a lot of if then else.
Since I have to create projection dynamically, I started with creating a method that returns dynamic projection selector based on certain parameters. Since the column that I wanted to select may differ in each query, I have to create different func based on parameter. So I have written a method that creates dynamic expression based on input parameter and then compile it to func which can be used as selector.
private FuncGetDynamicMappingFunc > new T1 { SomeText1 = o.SomeTextEN, SomeText2 = o.SomeTextPT }(string[] sourceFields, string[] targetFields) { //Objective: To generate a function dynamically that looks something like: //o =
//"o" var sourceParameterExpression = Expression.Parameter(typeof(T), "o"); //"new T1()" var targetNewExpression = Expression.New(typeof(T1)); var targetMemberBindings = new List<MemberBinding>(); for(int i = 0; i < sourceFields.Length; ++i) { //"SomeTextEN" //"SomeTextPT" var sourcePropertyInfo = typeof(T).GetProperty(sourceFields[i]); //"SomeText1" //"SomeText2" var targetPropertyInfo = typeof(T1).GetProperty(targetFields[i]); //"o.SomeTextEN" //"o.SomeTextPT" var sourceMemberExpression = Expression.Property(sourceParameterExpression, sourcePropertyInfo); //"SomeText1 = o.SomeTextEN" //"SomeText2 = o.SomeTextPT" var targetMemberAssignmentExpression = Expression.Bind(targetPropertyInfo, sourceMemberExpression); targetMemberBindings.Add(targetMemberAssignmentExpression); } //new T1 { SomeText1 = o.SomeTextEN, SomeText2 = o.SomeTextPT } var targetMemberInitExpression = Expression.MemberInit(targetNewExpression, targetMemberBindings); //"o => new T1 { SomeText1 = o.SomeTextEN, SomeText2 = o.SomeTextPT } Expression > lambda = Expression.Lambda >(targetMemberInitExpression, sourceParameterExpression); //Func Func func = lambda.Compile(); return func; }
Now I can use it like:
var selector = GetDynamicMappingFunc(new[] { "ShortName", "DescNL" }, new[] { "SomeText1", "SomeText2" }); var res = items.Select(selector);
No comments:
Post a Comment