当类型没有构造函数时如何在Linq中动态选择字段?

问题描述 投票:0回答:1

我正在尝试创建一个允许查询和返回动态字段的api。但是,以下行是有问题的,并引发运行时错误:

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

错误是:

类型'izsmmmo.Kurullar.Kurul'没有默认的构造函数

我所知道的是接口的类型,所以我无法创建实例。此代码是否可以修复,或者我需要另一种方式来构建自定义选择集?

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();
        }
    }
}
c# linq c1-cms
1个回答
0
投票

安装动态Linq nuget包解决了问题:

using System.Linq.Dynamic;

我需要在Select之后重新排列OrderBy,如下所示:

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)
    .Select(fields);

我没有性能问题,所以我可以在选择字段之前订购商品。

© www.soinside.com 2019 - 2024. All rights reserved.