Linq: Dynamic Select

LINQ : Dynamic select

You can do this by dynamically creating the lambda you pass to Select:

Func<Data,Data> CreateNewStatement( string fields )
{
// input parameter "o"
var xParameter = Expression.Parameter( typeof( Data ), "o" );

// new statement "new Data()"
var xNew = Expression.New( typeof( Data ) );

// create initializers
var bindings = fields.Split( ',' ).Select( o => o.Trim() )
.Select( o => {

// property "Field1"
var mi = typeof( Data ).GetProperty( o );

// original value "o.Field1"
var xOriginal = Expression.Property( xParameter, mi );

// set value "Field1 = o.Field1"
return Expression.Bind( mi, xOriginal );
}
);

// initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var xInit = Expression.MemberInit( xNew, bindings );

// expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
var lambda = Expression.Lambda<Func<Data,Data>>( xInit, xParameter );

// compile to Func<Data, Data>
return lambda.Compile();
}

Then you can use it like this:

var result = list.Select( CreateNewStatement( "Field1, Field2" ) );

Linq.Dynamic Select custom column with operation

You are using the DataRow item property to get the value for a field. This method returns an object which you can't add. You need to cast to the proper type.

"new (T[\"ss\"] as ss, T[\"xx\"] as xx, int(T[\"ss\"])+int(T[\"xx\"]) as yy)"

Dynamic LINQ expression for Select with child collection (Entity Framework)

My solution from the linked post handles quite simplified scenario. It can be extended for handling nested properties and method invocations, but then main problem will it is that it result isn't truly dynamic. It requires a predefined type and selectively selects/populates members of that type. Which makes it similar to AutoMapper explicit expansion feature, thus it might be better to use the later since it offers flexible automatic/manual mapping options.

For truly dynamic output you need a library which generates dynamic classes at runtime. Dynamic LINQ is one of them, and apart from its unusual expression language actually can be used for your scenario (at least the one from https://dynamic-linq.net/, because there are many flavors of that library and all they support/do not support some things).

Following is an example using System.Linq.Dynamic.Core package (or EF Core version of it Microsoft.EntityFrameworkCore.DynamicLinq in case you need async queryable support):

var selectList = new List<string>();
// Dynamic part
selectList.Add("ID");
selectList.Add("Name");
selectList.Add("Author.Name as AuthorName");
// Static part. But the nested Select could be built dynamically as well
selectList.Add("Posts.Select(new (Id, Name)) as Posts");

var listItems = _efDbContext.Blogs
.Select($"new ({string.Join(", ", selectList)})")
.ToDynamicList();


Related Topics



Leave a reply



Submit