I'm trying to create an api which one allows to query and return dynamic fields. However the line below is problematic and throws a runtime error:
// new statement "new T()"
var xNew = Expression.New(typeof(T));
The error is:
Type 'izsmmmo.Kurullar.Kurul' does not have a default constructor
All I know is the type is interface, so I cannot create an instance. Is this code can fixable or do I need another way to build custom select set?
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Http;
using Composite.Data;
namespace Composite.Controllers
{
public class TestController : ApiController
{
public object Get(string fields = "Onem, KurulAdi")
{
using (DataConnection connection = new DataConnection())
{
var kurullar = connection.Get<izsmmmo.Kurullar.Kurul>()
.Where(k => k.Aktif)
//.Select(x => new { KurulAdi = x.KurulAdi, Onem = x.Onem })
.Select(CreateNewStatement<izsmmmo.Kurullar.Kurul>(fields))
.OrderBy(k => k.Onem);
return kurullar;
}
}
private Func<T, T> CreateNewStatement<T>(string fields)
{
// input parameter "o"
var xParameter = Expression.Parameter(typeof(T), "o");
// new statement "new T()"
var xNew = Expression.New(typeof(T));
// create initializers
var bindings = fields.Split(',').Select(o => o.Trim())
.Select(o =>
{
// property "Field1"
var mi = typeof(T).GetProperty(o);
// original value "o.Field1"
var xOriginal = Expression.Property(xParameter, mi);
// set value "Field1 = o.Field1"
return Expression.Bind(mi, xOriginal);
}
);
// initialization "new Datax { Field1 = o.Field1, Field2 = o.Field2 }"
var xInit = Expression.MemberInit(xNew, bindings);
// expression "o => new Datax { Field1 = o.Field1, Field2 = o.Field2 }"
var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);
// compile to Func<Datax, Datax>
return lambda.Compile();
}
}
}