Мы создаем динамические поисковые выражения с использованием библиотеки Dynamic Linq. Мы столкнулись с вопросом о том, как создать выражение lamba с использованием динамической библиотеки linq для свойств навигации, которые имеют отношение один ко многим.
У нас есть следующее, что мы используем с оператором содержит
Person.Names.Select(FamilyName).FirstOrDefault()
Это работает, но есть две проблемы.
Конечно, он выбирает только имя FirstOrDefault (). Мы хотим, чтобы он использовал все имена для каждого человека.
Если для человека нет имен, Select выбрасывает исключение.
С обычным запросом это не так сложно, потому что мы можем сделать два из операторов, но лямбда-выражение более сложное.
Любые рекомендации будут оценены.
РЕДАКТИРОВАТЬ - Дополнительная информация о коде ... не динамическое выражение 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;}
}
Мы все продумали и сделали, но это было довольно сложно. Ниже приведены различные методы, как мы достигли конечного результата. Теперь нам просто нужно переосмыслить, как построен наш класс 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.
РЕДАКТИРОВАТЬ - В качестве альтернативы используйте просто select ... гораздо более простой ... но для этого требуется добавление метода Contains, как отмечено выше.
var results = persons.AsQueryable().Where("Names.Select(FamilyName)
.Contains(@0", "Smith)
Первоначально мы попробовали это, но столкнулись с ужасающим «Не существует подходящего метода агрегирования Contains». ошибка. Я вкратце рассказал о том, как мы решили проблему при попытке заставить работать SelectMany ... поэтому просто вернулись к методу Select.