0

I have a generic func that takes a string of fields and selects them from an object using linq. However the output is not type of object but a subset of. So to convert this new List<subsetOfOriginal> to a DataTable, I cannot use list.GetType() because it will get me Original.

I have converted

Func<T, T> CreateSelectStatement<T>(string fields)

to

Func<T, S> CreateSelectStatement<T, S>(string fields)

because I don't want TResult to be of type T. Not sure if this is the correct way. This is the code I have at the moment and how it is invoked.

Func<T, S> CreateSelectStatement<T, S>(string fields)
    {
        var xParameter = Expression.Parameter(typeof(T), "o");
        var xNew = Expression.New(typeof(T));
        var bindings = fields.Split(',').Select(o => o.Trim())
            .Select(o => {
        var mi = typeof(T).GetProperty(o);
        var xOriginal = Expression.Property(xParameter, mi);
        return Expression.Bind(mi, xOriginal);
            }
        );

        var xInit = Expression.MemberInit(xNew, bindings);
        var lambda = Expression.Lambda<Func<T, S>>(xInit, xParameter);
        return lambda.Compile();
    }

and then to invoke it I'm using

CreateSelectStatement<SP_ProjectAnalysis_NP, dynamic>(columns)

Expected outcome should be the fields that are loading correctly but the type of the object is as if I used p => new { }. Currently I am getting object as the return type and trying to perform the following gets me 0 properties:

private static DataTable ToDataTable<T>(IList<T> list, string tableName = "table")
        {
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
5
  • kindly fix the block codes for me (the pointed brackets do not want to show). Commented Jul 11, 2019 at 17:14
  • Perhaps get a copy of LINQPad and use the Dump statement to verify the lambda is what you expect? The code seems okay to me - but your usage perhaps not. If your calling Expression.New(typeof(T)) then by definition the result will be of type T and not type S. I believe dynamic is treated like object for Reflection, so you really need to have Func<T, T>. Also, what type is being passed into the returned Func? If it is already a T I don't see the point... Commented Jul 11, 2019 at 18:24
  • @NetMage Ok so that draws me closer to the solution or at least to a better explanation. I actually want to have Expression.New(typeof(S)) and not T, you're right. So the user is selecting columns from a table arbitrarily and I want S to dynamically become an object of the new class containing the new columns as properties. Because after that I am passing list of S to an excel creator. I don't want T because T will give me a lot of columns with null values then (the un-selected). Commented Jul 15, 2019 at 7:59
  • Perhaps consider LINQKit which includes runtime anonymous object creation? Unfortunately, creating anonymous objects at runtime is a lot of work (I think I might have posted the code here) but perhaps you could consider using something like DataTable? Commented Jul 15, 2019 at 13:37
  • Here is my simplified anonymous object creator code. Commented Jul 15, 2019 at 17:14

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.