【问题标题】:Selecting Columns in LINQ using System.Linq.Expressions API使用 System.Linq.Expressions API 在 LINQ 中选择列
【发布时间】:2012-07-02 18:22:54
【问题描述】:

我正在尝试使用 LINQ 表达式从 IEnumerable 动态选择列到我可以绑定到我的 UI 的结果集中。在这一点上,我很难掌握 LINQ 表达式中投影的基础知识。

假设我有一个这样的字符串列表:

Dim myStrings = {"one", "two", "three"}.ToList()

使用 lambda 表达式,我可以通过以下方式轻松选择字符串长度的集合:

Dim myStringLengths = myStrings.Select(Function(x) x.Length)

这个语句的结果会给我留下一个名为 myStringLengths 的集合,其中包含元素 3, 3, 5

我似乎无法弄清楚如何使用 LINQ 表达式产生等效结果。

编辑:当我说 LINQ 表达式时,我指的是在 System.Linq.Expressions 命名空间中使用 API,而不是 LINQ 语句或 lambda 表达式的标准形式。正如您在上面清楚地看到的那样,我已经熟悉如何以这种方式生成投影。

非常感谢任何帮助。

【问题讨论】:

标签: .net linq linq-expressions


【解决方案1】:
 var item = Expression.Parameter(typeof(string), "x");
 var length = Expression.PropertyOrField(item, "Length");

 new string[] {"one", "two", "three"}
      .AsQueryable()
      .Select(Expression.Lambda<Func<string, int>>(length, item));

您需要一个 IQueryable 才能使用表达式(您可以使用 ToList 或类似方法将其带回 IEnumerable)。 然后将 Lambda 生成为表达式树(长度示例在上面完成)。 对不起,它在 C# 中

【讨论】:

  • 如果您在编译时不知道类型,则表达式会变得有点复杂,因为您需要包含转换表达式以将输入参数转换为正确的类型(在运行时派生)在访问该字段之前。我发现最简单的方法是编写你想要使用的 lambda,然后将其解构为表达式操作。
  • 不错。我在看Expression.Lambda...但是为什么呢?你不能直接去Expression.PropertyOrField吗?
  • 因为 Select 将 func 作为其参数(它是从一个对象到另一个对象的投影)。像任何其他方法调用一样,您必须遵守签名。 System.Linq.Queryable.Select(this System.Linq.IQueryable, System.Linq.Expressions.Expression>)
  • 谢谢,这更像我正在寻找的。我必须跨越的一个障碍是,目前我有一个非通用的 IEnumerable 可以使用。这使我什至无法使用 .Select() (至少我还没有找到方法)。我有一个要选择的字段的 PropertyInfo 对象,所以我有属性的名称和类型,以及基础类的类型,可供我使用。我会稍微解构 lambda。
  • 对于非泛型的 IEnumerable 有一个 AsQueryable 的重载,只需要更多的表达式来投射项目。
【解决方案2】:

在 C# 中它看起来像这样

var myStringLengths = myStrings
                        .Select((s) => s.Length);

【讨论】:

  • 这就是我上面使用的VB语句的C#版本。
  • @MikeC 是的,您能否举一个更好的例子来说明您在问题中要查找的内容。起始值和结束值会有所帮助。
  • 我在上面添加了我的查询的明确预期结果,它只不过是代表字符串长度的整数集合。起始值和所需操作已在问题中。
猜你喜欢
  • 1970-01-01
  • 2012-08-07
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
相关资源
最近更新 更多