嗨,我需要使用动态属性名称调用 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();
}
}
我用以下代码解决了我的问题并使用这个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);
}