使用表达式在运行时动态选择属性

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

嗨,我需要使用动态属性名称调用 LINQ 选择器。 但 LINQ 选择器无法返回属性名称中存在的数据。


其以下代码是我的问题的模拟示例代码

    public class DataService
    {
        public record Data(int Id, string Name, string Title, string Comment);

        private static readonly IList<Data> datas;
        static DataService()
        {
            datas = new List<Data>();
            //*Fill datas from db or file or static codes*
        }
        public IList<Data> Get(params string[] selector)
        {
            return datas.Select(selector).ToList(); 
        }
    }

c# linq expression
1个回答
0
投票

我用以下代码解决了我的问题并使用这个answer

public static IEnumerable<T> Select<T>(this IEnumerable<T> source, params string[] propertyNames) => source.AsQueryable().Select(propertyNames);
public static IQueryable<TResult> Select<TResult>(this IQueryable<TResult> source, params string[] propertyNames)
{
    var resultType = typeof(TResult);
    var properties = resultType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
    var selectedProperties = properties.Where(p => propertyNames.Contains(p.Name) && p.CanWrite).ToList();

    var sourceType = source.ElementType;
    var parameter = Expression.Parameter(sourceType, "e");
    var bindings = selectedProperties.Select(q => Expression.Bind(q, Expression.PropertyOrField(parameter, q.Name))).ToList();

    var instance = Expression.New(resultType);
    var body = Expression.MemberInit(instance, bindings);

    var selector = Expression.Lambda(body, parameter);
    var quote = Expression.Quote(selector);
    var call = Expression.Call(typeof(Queryable), "Select", [sourceType, resultType], source.Expression, quote);
    return source.Provider.CreateQuery<TResult>(call);
}
© www.soinside.com 2019 - 2024. All rights reserved.