LINQ 확장 메서드가있는 여러 WHERE 절
다음과 같은 LINQ 쿼리가 있습니다.
DateTime today = DateTime.UtcNow;
var results = from order in context.Orders
where ((order.OrderDate <= today) && (today <= order.OrderDate))
select order;
LINQ를 배우고 이해하려고합니다. 어떤 경우에는 두 개의 추가 WHERE 절을 추가해야합니다. 이를 위해 다음을 사용하고 있습니다.
if (useAdditionalClauses)
{
results = results.Where(o => o.OrderStatus == OrderStatus.Open) // Now I'm stuck.
}
보시다시피 WHERE 절을 추가하는 방법을 알고 있습니다. 하지만 여러 개를 어떻게 추가합니까? 예를 들어, 나는 추가하고 싶습니다
WHERE o.OrderStatus == OrderStatus.Open AND o.CustomerID == customerID
내 이전 쿼리에. 확장 메서드를 사용하여 어떻게합니까?
감사합니다!
두 가지 방법:
results = results.Where(o => (o.OrderStatus == OrderStatus.Open) &&
(o.CustomerID == customerID));
또는:
results = results.Where(o => (o.OrderStatus == OrderStatus.Open))
.Where(o => (o.CustomerID == customerID));
나는 보통 후자를 선호합니다. 그러나 SQL 서버를 프로파일 링하여 쿼리 실행을 확인하고 어떤 것이 데이터에 대해 더 나은지 확인하는 것이 좋습니다 (차이가있는 경우).
.Where()메서드 연결에 대한 참고 사항 : 원하는 모든 LINQ 메서드를 함께 연결할 수 있습니다. 같은 메소드 .Where()는 실제로 데이터베이스에 대해 실행되지 않습니다 (아직). 이들은 실행을 지연 실제 결과 (예와 같이 계산 될 때까지 .Count()또는 .ToList()). 따라서 여러 메서드를 함께 연결하면 ( .Where(), .OrderBy()또는 그 효과에 대한 더 많은 호출 등) 표현식 트리 라는 것을 구축합니다 . 이 전체 트리는 평가할 때가되면 데이터 소스에 대해 실행되는 것입니다.
한 것처럼 계속 연결할 수 있습니다.
results = results.Where (o => o.OrderStatus == OrderStatus.Open);
results = results.Where (o => o.InvoicePaid);
이것은 AND를 나타냅니다.
메모리 내 데이터 ( "POCO 컬렉션"읽기)로 작업하는 경우 다음과 같이 PredicateBuilder를 사용하여 식을 함께 스택 할 수도 있습니다 .
// initial "false" condition just to start "OR" clause with
var predicate = PredicateBuilder.False<YourDataClass>();
if (condition1)
{
predicate = predicate.Or(d => d.SomeStringProperty == "Tom");
}
if (condition2)
{
predicate = predicate.Or(d => d.SomeStringProperty == "Alex");
}
if (condition3)
{
predicate = predicate.And(d => d.SomeIntProperty >= 4);
}
return originalCollection.Where<YourDataClass>(predicate.Compile());
언급 된 전체 소스는 다음과 같습니다 PredicateBuilder(하지만 몇 가지 예를 더 포함 하여 원본 페이지 를 확인할 수도 있습니다 ).
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
참고 : 이식 가능한 클래스 라이브러리 프로젝트 에서이 접근 방식을 테스트 .Compile()했으며 작동 하도록 사용해야 합니다.
Where (predicate .Compile () );
확실히:
if (useAdditionalClauses)
{
results =
results.Where(o => o.OrderStatus == OrderStatus.Open &&
o.CustomerID == customerID)
}
또는 다음 .Where()과 같은 또 다른 호출 (다른 부울 제어 변수로 분할되지 않는 한 왜 원하는지 모르겠지만) :
if (useAdditionalClauses)
{
results = results.Where(o => o.OrderStatus == OrderStatus.Open).
Where(o => o.CustomerID == customerID);
}
또는 다른 재 할당 results:`results = results.Where ( blah ).
you can use && and write all conditions in to the same where clause, or you can .Where().Where().Where()... and so on.
results = context.Orders.Where(o => o.OrderDate <= today && today <= o.OrderDate)
The select is uneeded as you are already working with an order.
Just use the && operator like you would with any other statement that you need to do boolean logic.
if (useAdditionalClauses)
{
results = results.Where(
o => o.OrderStatus == OrderStatus.Open
&& o.CustomerID == customerID)
}
참고URL : https://stackoverflow.com/questions/8791540/multiple-where-clauses-with-linq-extension-methods
'Nice programing' 카테고리의 다른 글
| '관리자 권한으로 실행'시 Windows 배치 파일 시작 디렉터리 (0) | 2020.10.31 |
|---|---|
| JSON 객체에서 jQuery의 find () 사용 (0) | 2020.10.31 |
| Internet Explorer 9에서 표준 문서 모드를 사용하도록 강제 (0) | 2020.10.31 |
| 객체에 우선 순위 대기열 STL을 사용하는 방법은 무엇입니까? (0) | 2020.10.31 |
| 지정된 하나를 제외한 모든 열의 DataFrame 검색 (0) | 2020.10.31 |