2014-12-23 3 views
2

Я хочу, чтобы выполнить динамический Lambda в коллекции с массивом строк [] на нем:Dynamic Lambda условия вложенного массива

public class ClassStudentsViewModel 
{ 
    public string[] Disciplines { get; set; } 
    public TeacherName { get; set; } 
} 

Это то, что я пытаюсь:

enter image description here

source - это коллекция ClassStudentsViewModel, а values - это массив строк с одной строкой. При выполнении, он бросает мне это исключение:

Нет Свойство или поле «у» существует в типа «String»

После некоторых поисков, я нашел this question что почти та же проблема, и OP закончил , изменив исходный код Dynamic.cs, это не очень хороший вариант для меня. Интересно, что я пытаюсь не поддерживать или быть ошибкой. Проблема в том, что упомянутый выше вопрос был задан почти 4 года назад.

Следующий фрагмент кода работает хорошо:

classStudents.AsQueryable().Where(x => x.Disciplines.Any(y => y == "Turma 2")).ToList(); 

Как я могу избавиться от этой ошибки?

UPDATE:

Немного контекста того, что я пытаюсь: Мой контроллер получает ViewModel с коллекцией фильтров, посланной сеткой 3 партии, которая содержит в основном значение и оператором , как eq, gt и т. Д. Метод включает все эти фильтры и преобразования на лямбда-операторах, например eq - == или contains - .Contains(). В простом строковом свойстве, например TeacherName (обновленный viewModel выше), динамические фильтры работают, например. если predicate на скриншоте: "TeacherName.Contains(@0)" он хорошо работает.

ОБНОВЛЕНИЕ 2:

Этот код генерирует предикат:

public static string ToLambdaOperator(string field, string oper, int index, string sufix = null) 
{ 
    var result = String.Empty; 

    switch (oper) 
    { 
     case "eq": 
     case "neq": 
     case "gte": 
     case "gt": 
     case "lte": 
     case "lt": 
      result = string.Format(field + ToLinqOperator(oper) + "@" + index); 
      break; 

     case "startswith": 
      result = field + ".StartsWith(" + "@" + index + ")"; 
      break; 

     case "endswith": 
      result = field + ".EndsWith(" + "@" + index + ")"; 
      break; 

     case "contains": 
      result = field + ".Contains(" + "@" + index + ")"; 
      break; 

     case "doesnotcontain": 
      result = "!" + field + ".Contains(" + "@" + index + ") || " + field + ".Equals(String.Empty)"; 
      break; 
    } 

    if (!String.IsNullOrEmpty(sufix)) 
    { 
     result += sufix; 
    } 

    return result; 
} 

// Use example 
var operator = "eq"; 
var paramCounter = -1; 
var predicate = ToLambdaOperator("Disciplines.Any(y => y", operator, ++paramCounter, ")"); 

Предикат выше приведет: Disciplines.Any(y => y == @0). Оператор contains приведет к следующему: Disciplines.Any(y => y.Contains(@0)).

+1

Это не понятно, почему вы должны использовать динамический LINQ вообще здесь. Что в вашем случае динамично? –

+0

@JonSkeet Я создаю это выражение снаружи для фильтрации виджета сетки сторонних разработчиков. – DontVoteMeDown

+0

Это не ужасно четкое описание - это не дает нам больше контекста.Не могли бы вы выполнить * эту * часть запроса с нормальным LINQ to Objects, а затем использовать это как источник динамического LINQ для интеграции виджета? –

ответ

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