【问题标题】:How to get single column with LINQ in anonymous method如何在匿名方法中使用 LINQ 获取单列
【发布时间】:2013-12-14 21:37:05
【问题描述】:

如何使用 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();

提前致谢。

【问题讨论】:

  • “它不起作用”并没有给我们任何有用的信息。你的Where 子句有什么意义? GetProperty(propName) 只会返回具有该名称的属性...这就是重点。
  • 他可能正在尝试做base.Query&lt;Product&gt;().Pluck("ProductName").AsEnumerable();
  • 我的意思是像 SQL 中的 Select ProductName [Name] From Productbase.Query&lt;Product&gt;().Select(x =&gt; new { Name = x.ProductName }).AsEnumerable();

标签: c# linq anonymous-methods


【解决方案1】:

这个条件不正确,因为当属性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));

【讨论】:

    【解决方案2】:

    调用 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);
    

    【讨论】:

    • 我想获取基于特定属性的所有值。我已经尝试过您的建议,但在“TProperty”上出现错误。你能解释更多吗?
    • 我将 TResult 更改为对象并且它可以工作。我有更多问题,我可以这样输入匿名类型吗? base.Query&lt;Product&gt;().Selec(x =&gt; new { Name = x.ProductName });
    【解决方案3】:

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

    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));
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2012-11-01
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      相关资源
      最近更新 更多