如何在匿名方法中使用LINQ获取单列

本文关键字:LINQ 获取 单列 方法 | 更新日期: 2024-09-25 08:21:28

如何使用linq表达式使用匿名方法获取单列。这是我的代码,它不起作用:

public IEnumerable<object> GetPropertyValues<T>(string propName) where T : class
{
    return base.Query<T>().AsEnumerable()
        .Where(x => x.GetType().GetProperty(propName).Name == propName)
        .Select(x => x.GetType().GetProperty(propName).GetValue(x, null));
}

以下是非通用方法中的代码:

base.Query<Product>().Select(x => x.ProductName).AsEnumerable();

提前谢谢。

如何在匿名方法中使用LINQ获取单列

此条件不正确,因为当属性propName丢失时,它会崩溃,而不是返回false:

.Where(x => x.GetType().GetProperty(propName).Name == propName)

如果你想说"动态类型具有属性propName",它的一个适当条件如下:

.Where(x => x.GetType().GetProperty(propName) != null)

注意,只有当T的某些(而不是全部)子类具有所需的属性propName时,这才是必要的。如果属性存在于T本身中,则可以提前获取属性,并执行以下查询的其余部分:

var theProp = typeof(T)..GetProperty(propName);
return base.Query<T>().AsEnumerable().Select(x => theProp.GetValue(x, null));

一旦调用AsEnumerable(),所有进一步的过滤都将发生在内存中,而不是SQL中。因此,你可以做:

var prop = typeof(T).GetProperty(propName);
return base.Query<T>().AsEnumerable().Select(t => prop.GetValue(t));

但这将在向下过滤到仅一列之前将T的所有列选择到存储器中。要在SQL中进行过滤,您需要动态构建一个表达式:

var prop = typeof(T).GetProperty(propName);
var parameter = Expression.Parameter(typeof(T));
var memberAccess = Expression.MakeMemberAccess(parameter, prop);
var selector = Expression.Lambda<Func<T, TProperty>>(memberAccess, parameter);
return base.Query<T>().Select(selector);

对于任何类型的对象的枚举。。。

public static IEnumerable<Object> Pluck<Object>(this IEnumerable<Object> source, string propName)
{
    return source
        .Select(x => new {
            obj: x
            prop: x.GetType().GetProperty(propName)
        })
        .Where(x => x.prop != null)
        .Select(x => x.prop.GetValue(x.obj));
};

对于单一类型对象的枚举。。。

public static IEnumerable<Object> Pluck<T>(this IEnumerable<T> source, string, propName)
{
    var prop = typeof(T).GetProperty(propName);
    return prop == null
         ? Enumerable.Empty<Object>()
         : source.Select(x => prop.GetValue(x));
};