Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a dynamic LINQ select projection function from a string[] of names?

Tags:

c#

linq

Using C#...

Is there any way to specify property names for a projection function on a LINQ select method, from an array.

public class Album
{
    public int Id { get; set; }
    public string Name { get; set; }
    public short Rate { get; set; }
    public string Genre { get; set; }
    public short Tracks { get; set; }
}

public class Class1
{
    private void Some<T>()
    {
        // Example of source
        var names = new[] { "Id", "Name", "Tracks" };

        var query = myDataContext.
                    GetTable<T>.
                    AsQueryable().
                    Select( /* dynamic projection from names array */ );

                    // something like
                    // Select(x => new
                    //     {
                    //         x.Id,
                    //         x.Name,
                    //         x.Tracks
                    //     }

        GoAndDoSomethingWith(query);
    }
}

Could this be done without System.Linq.Dynamic?

like image 366
Shin Avatar asked Dec 11 '14 00:12

Shin


People also ask

Can you use Linq on dynamic?

The Dynamic source file includes a helper library that allows you to express LINQ queries using extension methods that take string arguments instead of type safe operators. To use the Dynamic Expression API, you could simply copy/paste the Dynamic source file in your project.

What is Dynamic Linq?

The Dynamic LINQ library exposes a set of extension methods on IQueryable corresponding to the standard LINQ methods at Queryable, and which accept strings in a special syntax instead of expression trees.

What is projection in Linq?

In LINQ, projection is an operation which converts an object into the new form which holds only those properties that will be subsequently used. By using projection, a developer can create a new type which is built from each object.


1 Answers

You could use reflection and dynamic types to generate an object with only the specified fields/properties.

Below is a simple way of doing this. You can do optimizations, like having a type cache for the reflection. But this should work for simple fields/properties.

public static object DynamicProjection(object input, IEnumerable<string> properties)
{
    var type = input.GetType();
    dynamic dObject = new ExpandoObject();
    var dDict = dObject as IDictionary<string, object>;

    foreach (var p in properties)
    {
        var field = type.GetField(p);
        if (field != null)
            dDict [p] = field.GetValue(input);

        var prop = type.GetProperty(p);
        if (prop != null && prop.GetIndexParameters().Length == 0)
            dDict[p] = prop.GetValue(input, null);
    }

    return dObject;
}

Usage:

//...
var names = new[] { "Id", "Name", "Tracks" };
var projection = collection.Select(x => DynamicProjection(x, names));
//...
like image 127
Xenolightning Avatar answered Sep 20 '22 14:09

Xenolightning