Po pierwsze, muszę powiedzieć, że przeczytałem kilka postów na ten temat w StackOverflow, ale nie mogę uzyskać pożądanego rezultatu.Linq-to-SQL łączące dwa wyrażenia <Func <T, bool>> ("gdzie klauzula") z i/lub
Pozwolę sobie wyjaśnić kontekst (uproszczony): używam Linq-to-SQL do zapytania klientów o ostatnie wizyty w sklepie i (opcjonalnie) dostaję tylko tych z pewną ilością płatności. Załóżmy, że mam model z klientami, wizytami i klasami płatności.
Więc, koncentrując się na ekspresji Where
, próbuję to:
Expression<Func<Entityes.Clients, bool>> filter = null;
filter = c =>
c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince));
if (minPayment.HasValue && minPayment.Value > 0)
{
filter.And(
c => c.Payments.Sum(p => p.Quantity) > minPayment.Value);
}
Sposób filter.And
jest metoda rozszerzenie, zalecana na tym forum, poniżej można zobaczyć definicję:
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2)
{
InvocationExpression invokedExpression =
Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
Nie działa to jednak zgodnie z oczekiwaniami, a wyniki nie są filtrowane według kwoty płatności. Nie ma błędu w danych lub modelu LINQ-SQL, ponieważ ten kod działa poprawnie:
filter = c =>
c.Visits.Any(v => v.VisitDate > DateTime.Now.Date.AddMonths(-(int)visitsSince)))
&& c => c.Payments.Sum(p => p.Quantity) > minPayment.Value;
Jednak nie chcę używać ostatniego kodu bo mam jakieś bardziej skomplikowane scenariusze, w których muszę buduj wyrażenie filtru krok po kroku za pomocą kombinacji "i/lub" każdej części.
PD: Jestem facetem "ADO.Net DataSets" próbującym nauczyć się Linq-SQL i wkrótce Entity Framework, mam nadzieję, że wkrótce będę przydatny dla społeczności StackOverflow.
p.s., powinieneś używać metody 'Expression.AndAlso()' do generowania logicznego wyrażenia AND ('&&'). 'Expression.And()' generuje bitowe wyrażenie AND ('&'). –