Динамическое выражение поиска Linq в свойствах навигации - PullRequest
1 голос
/ 03 марта 2011

Мы создаем динамические поисковые выражения, используя библиотеку Dynamic Linq.Мы столкнулись с вопросом, как создать выражение lamba, используя динамическую библиотеку linq для свойств навигации, которые имеют отношение один ко многим.

У нас есть следующее, которое мы используем с оператором contains-

 Person.Names.Select(FamilyName).FirstOrDefault()

Работает, но есть две проблемы.

  1. Конечно, выбирается только имя FirstOrDefault ().Мы хотим, чтобы он использовал все имена для каждого человека.

  2. Если для человека нет имен, выбор выбирает исключение.

С обычным запросом это не так сложно, потому что мы можем сделать два оператора from, но лямбда-выражение более сложное.

Буду признателен за любые рекомендации.

EDIT- Дополнительная информация о коде..не динамическое выражение linq выглядело бы примерно так.

 var results = persons.Where(p => p.Names.Select(n => n.FamilyName).FirstOrDefault().Contains("Smith")).ToList();

, а класс выглядит следующим образом -

public class Person
{
 public bool IsActive { get; set;}

 public virtual ICollection<Name> Names {get; set;}
}

public class Name
{
public string GivenName { get; set; }

public string FamilyName { get; set; }

public virtual Person Person { get; set;}
}

1 Ответ

2 голосов
/ 04 марта 2011

Мы все продумали и сделали, но это было довольно сложно. Ниже приведены различные методы того, как мы достигли конечного результата. Теперь нам просто нужно переосмыслить, как создается наш класс SearchExpression ... но это уже другая история.

1. Синтаксис эквивалентного запроса

var results = from person in persons
from name in person.names
where name.FamilyName.Contains("Smith")
select person;

2. Эквивалентный лямбда-синтаксис

var results = persons.SelectMany(person => person.Names)
                     .Where(name => name.FamilyName.Contains("Smith"))
                     .Select(personName => personName.Person);

3. Эквивалентный лямбда-синтаксис с динамическим Linq

var results = persons.AsQueryable().SelectMany("Names")
                     .Where("FamilyName.Contains(@0)", "Smith")
                     .Select("Person");

Примечания - Вам потребуется добавить метод Contains в библиотеку Dynamic Linq.

РЕДАКТИРОВАТЬ - в качестве альтернативы использовать только выбор ... гораздо более простой ... но это требует добавления метода Contains, как отмечено выше.

var results = persons.AsQueryable().Where("Names.Select(FamilyName)
                                   .Contains(@0", "Smith)

Первоначально мы пытались это сделать, но столкнулись с ужасным «Не существует применимого статистического метода Contains». ошибка. Я много раз говорил о том, как мы решили проблему при попытке заставить работать SelectMany ... поэтому просто вернулись к методу Select.

...