2012-07-02 4 views
3

Я пытаюсь использовать выражения LINQ для динамического выбора столбцов из IEnumerable в результирующий набор, который я могу привязать к своему пользовательскому интерфейсу. В этот момент мне трудно усвоить основы проектирования в выражениях LINQ.Выбор столбцов в LINQ с использованием System.Linq.Expressions API

Скажем, у меня есть список строк, например, так:

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

Использование лямбда-выражения можно легко выбрать из коллекции длины строки, выполнив:

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

В результате этого заявления оставил бы меня с коллекцией под названием myStringLengths, имеющей элементы 3, 3, 5.

Что я могу не понять, так это то, как я могу произвести эквивалентный результат, используя выражение LINQ.

Edit: Когда я говорю выражение LINQ, я говорю об использовании API в System.Linq.Expressions пространстве имен, а не стандартную форму выражения Постулаты или лямбда LINQ. Как вы можете ясно видеть выше, я уже знаком с тем, как генерировать проекцию таким образом.

Любая помощь очень ценится.

+0

[Dynamic Linq] (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query -library.aspx) позволяет выбирать столбцы во время выполнения. –

+0

Я бы предпочел не строить свои выражения, используя строки. – mclark1129

+0

Какое выражение вы хотите построить? – Hogan

ответ

3
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 использовать выражение (вы можете вернуть его к IEnumerable с ToList или похожий). Затем вы создаете Лямбду как дерево выражений (пример длины выполняется выше). Извините его в C#

+0

Если вы не знаете типы во время компиляции, выражение будет немного более сложным, так как вам нужно будет включить выражения для выражения для ввода входного параметра в правильный тип (полученный во время выполнения) перед доступом к полю.Самый простой способ, который я нахожу, - написать лямбду, которую вы хотите использовать, а затем деконструировать в операциях выражения. –

+0

Ницца. Я смотрел на «Expression.Lambda» ... но почему? Не могли бы вы просто пойти прямо к 'Expression.PropertyOrField'? – Hogan

+0

Поскольку Select принимает func как свой аргумент (его проекция от одного объекта к другому). Как и любой другой вызов метода, вы должны подчиняться подписи. System.Linq.Queryable.Select (этот System.Linq.IQueryable , System.Linq.Expressions.Expression >) –

0

В C# это будет выглядеть следующим образом

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

Это просто версия C# из выражения VB, которое я использовал выше. – mclark1129

+0

@MikeC Да, не могли бы вы дать лучший пример того, что вы ищете в своем вопросе. Начальные и конечные значения помогут. – Hogan

+0

Я добавил явный ожидаемый результат моего запроса выше, это не более чем набор целых чисел, представляющих длину строк. Начальные значения и желаемая операция уже находятся в вопросе. – mclark1129