Я создаю отчет, чтобы перечислять людей в моей базе данных в соответствии с определяемыми пользователем критериями фильтра. Так, например, я мог фильтровать по имени, возраста и т.д.Как написать выражение Linq для перекрестного соединения SQL?
var people = db.People.AsQueryable();
if (filterByName)
people = people.Where(p => p.LastName.Contains(nameFilter));
if (filterByAge)
people = people.Where(p => p.Age == age);
Теперь, один из критериев фильтра, чтобы показать людям, которые не имели свои необходимые прививки. У меня есть таблицы для Immunization
и PersonImmunization
(с уникальным индексом на PersonID, ImmunizationID
). Если кто-то пропустил какие-либо записи PersonImmunization
, или если количество доз, которое они получили, под этим требованием, они должны быть включены, в противном случае нет.
Если бы я писал запрос SQL, это было бы:
select p.*
from Person p
cross join Immunization i
left join PersonImmunization pi
on pi.PersonID = p.ID and pi.ImmunizationID = i.ID
where pi.ID is null or pi.Doses < i.RequiredDoses;
Теперь для того, чтобы сделать эту часть моего ИНЕК, мне нужно, чтобы выразить это с помощью Expression
предиката:
if (filterByImmunizations) {
Expression<Func<Person, bool>> nonCompliantImmunization =
person => <now what?>;
people = people.Where(nonCompliantImmunization);
}
Первой проблемой, с которой я столкнулся, является работа с иммунизациями в выражении. Затем, как только у меня есть это, я подозреваю, что поиск несовместимых людей может быть более простым, но если бы вы могли включить это в свой ответ, я был бы очень признателен!
EDIT: Мне было предложено объяснить, почему я так настроен на получение решения, используя Expression<Func<Person, bool>>
. Причина в том, что я создал целую общую структуру для написания сложных пользовательских запросов в нескольких разных контекстах. Чтобы дать вам представление о том, что внутри двигателя, вот фрагмент того, что находится внутри моего базового класса:
public abstract class QueryBuilder<T> where T : EntityObject {
public static IQueryable<T> FilterQuery(IQueryable<T> query, IEnumerable<QueryConditionLite> filters, bool anyConditionSufficient) {
...
}
protected Expression<Func<TBase, bool>> GetPredicate(Expression<Func<TBase, double>> expression, IQueryCondition condition) {
...
}
}
Тогда у меня есть PersonQueryBuilder : QueryBuilder<Person>
, и в том, что я хочу, чтобы создать фильтр, который показывает людей, которые не - согласуется с их требованиями к иммунизации. Я думаю, вы согласитесь, что синтаксис запроса просто не собирается его вырезать.
@Nilesh - The que stion отталкивается от моего фактического кода, чтобы предотвратить путаницу; просто примите, что мне нужно выражение 'Expression>', а синтаксис запроса недостаточен для моих целей. –
Измените свой вопрос, чтобы добавить свое обоснование для запрета действительных рабочих решений. –
Почему вы, кажется, думаете, что можете использовать только запрос .Where (...)? – Tory