2012-05-08 3 views
0

У меня в настоящее время есть часть Linq, которая выглядит примерно так:Могу ли я генерировать выражение linq динамически в C#?

List<dynamic> childrenToBeRemoved = this.ItemsSource.Where(o => o.ParentID == "1234").ToList(); 

где ItemsSource - наблюдаемый набор динамики.

Это прекрасно работает, но проблема заключается в том, что ParentID является свойством, которое может варьироваться. Например. его можно назвать ParentPkey или ParentKey и т. д.

Могу ли я создать выражение, в котором я могу указать свойство, которое я хочу использовать в своем сравнении?

Я пробовал использовать динамический linq, но он не работает с использованием набора динамиков, отлично работает с коллекцией pocos.

Спасибо ...

+0

Почему это условие может измениться? ... почему бы не сделать 'Func ', который вы затем вводите как' this.ItemSource.Where (myFunc) 'вместо того, чтобы сделать сам параметр динамическим (это все еще возможно, но накладные расходы в выражениях и дженериках могут не стоить Это)? –

+2

[да, вы можете] (http://msdn.microsoft.com/en-us/library/bb397951.aspx), но это похоже на то, что вы используете динамический дробовик, чтобы убить статическую муху. –

+0

Условие такое же, но свойство, которое я использую в этом выражении, может измениться, я рассматриваю здание как условие, используя построитель дерева выражений, но ваш правильный выглядит как массивный молот и очень маленький гвоздь. Учитывая, что свойство может меняться, как выглядит первый подход Func ? –

ответ

0

Помещенных вы Linq выражения в функцию, и передать это свойство в качестве параметра.

0

Если вы знаете тип ваших элементов, вы можете использовать отражение:

PropertyInfo parentProp = itemType.GetProperty("ParentKey or whatever"); 
List<dynamic> childrenToBeRemoved = this.ItemsSource.Where(o => Equals("1234", parentProp.GetValue(o, null))).ToList(); 
+0

этот тип-сейф? что, если свойство не является типом 'System.String'? –

+0

Правильно, он даже не компилируется, я исправил для более надежного использования Equals – Julien

+0

и как вы могли бы сравнить его с «null»? :) ... почему бы не использовать 'Equals()' (статическая реализация на 'System.Object')? Основная проблема, которую вы получите в этом сценарии, заключается в том, что вам придется получить все записи в вашем домене, так как это сравнение не может быть переведено на EF или аналогично ... –

4

почему сделать сама реализация динамической? вы можете просто сделать динамический вызов!

IEnumerable<MyItem> result; 
if (condition1) 
{ 
    result = this.Items.Where(arg => arg.ProductId == "123"); 
} 
else if (condition2) 
{ 
    result = this.Items.Where(arg => arg.ProductPK == "123"); 
} 

или

Func<Item, bool> predicate; 
if (condition1) 
{ 
    predicate = item => item.ProductId == "123"; 
} 
else if (condition2) 
{ 
    predicate = item => item.ProductPK == "123"; 
} 
var result = this.Items.Where(predicate); 

Тааак ... Я считаю, что вы должны сказать нам больше о вашей актуальной проблеме - я не вижу текущую потребность в реализации н - так, я считаю ваше требование плохо -определенный!

4

это не имеет значения, если запрос является динамическим LINQ или не

Expression<Func<Entity, int>> predicate = x => x.Id == myvalue; 
from entity in _context.Entities.Where(predicate) 
select entity; 

Заканчивать PredicateBuilder из LinkKit @http://www.albahari.com/nutshell/linqkit.aspx есть достаточно примеров там, а

Ответственность перевода выражения для соответствующего SQL лежит на провайдере linq, поэтому убедитесь, что поставщик, которого вы используете, поддерживает соответствующие аспекты.

Смежные вопросы