2009-10-26 2 views
2

아래 옵션 블록의 일부 아래에 ProjectID 확인을 할 수있는 방법이 있습니까? 저는 Java EE에서 최근의 .Net 변환이며 Hibernate Criteria API와 비슷한 것을 찾고 있습니다. 아래 블록을 단순화하고 Where()를 한 번만 호출하면됩니다. 또한 일주일 전에 .Net으로 작업하기 시작하면서 Lambda로 Where()를 수행하는 것이 성능에 미치는 영향에 대해서 확신 할 수 없습니다.Linq.Table.Where()의 선택적 OR 구문 사용

쿼리가 처음으로까지 해석 및 실행되지 않습니다
Expression<Predicate<Project>> predicate = p => p.ProjectDescription.Contains(search); 
if (isID) 
    predicate = p => predicate(p) || p.ProjectID == projectId; 

return dataContext.Where(predicate); 

답변

3

당신이 선택적으로 AND xyz을 추가 찾고 있다면, 당신은 단순히 Where 전화를 체인 수 있습니다. 이를 위해서는 술어 표현식을 직접 작성해야합니다. 예쁜 것은 아닙니다. 이 작업을 수행하는 한 가지 방법은 우리가 완전히 식을 다시해야하기 때문에 기존의 조건에 조건을 추가하면, 초기 식을 만드는 것보다 더 많은 일을하다

Expression<Func<Project, bool>> predicate = p => p.ProjectDescription.Contains(search); 
if (isID) 
{ 
    ParameterExpression param = expr.Body.Parameters[0]; 
    predicate = Expression.Lambda<Func<Project, bool>>(
     Expression.Or(
      expr.Body, 
      Expression.Equal(
       Expression.Property(param, "ProjectID"), 
       Expression.Constant(projectID))), 
     param); 
} 
var projects = dataContext.Projects.Where(predicate); 

주입니다. (술어는 항상 하나의 매개 변수를 사용해야하며, 람다 구문을 사용하여 두 개의 표현식을 선언하면 각 술어마다 하나씩 두 개의 매개 변수 표현식 객체가 생성됩니다.) C# 컴파일러는 람다 구문을 초기 술부.

Hibernate에 대한 조건 API에 익숙하다면 좀 익숙 할 것입니다. 조금 더 자세히 설명합니다.


은 참고 다음은도 작동 할 수는 있지만, 일부 LINQ 구현은 꽤 똑똑 것을, 그래서 :

var projects = dataContext.Projects.Where(
    p => p.ProjectDescription.Contains(search) 
     || (isID && p.ProjectID == projectID)); 

YMMV는하지만, 이렇게 생성 된 SQL을 확인 않습니다.

+0

그렇지만 이것은 Hibernate에서 새로운 Criterion을 만드는 것보다 훨씬 복잡 해 보인다. 나는 LINQ가 그런 것을 지원하지 않는다고 추측하고있다. –

+0

사실, 매우 장황합니다. 그러나 상황에 맞는 바로 가기가있을 수 있습니다. 나는 이것을 언급하기 위해 설명을 확장했다. – Ruben

0

대표/표현식 (안된 의사 코드)과 같이, "체인"할 수있다 IQueryable. 그러므로 아무리 많은 부분을 추가해도 계속해서 DB를 여러 번 치는 것에 대해 걱정할 필요가 없습니다.

var projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search)); 
if (isID) 
    projects = projects.Where(p => p.ProjectID == projectID); 

불행하게도 일이 당신이 OR xyz을하고자 할 때 너무 쉽게되지 않습니다

+0

불행히도 컴파일되지 않습니다. 표현식은 이와 같은 표현식 내에서 호출 될 수 없습니다. – Ruben

+0

LINQ에서이 작업을 수행 할 수있는 다른 방법이 있습니까? 아마 Lambdas없이? –

+0

작동해야하는 예제를 제공했지만 꽤 좋지는 않습니다. – Ruben

1

가 실제로의 요소에 액세스 :

public IQueryable<Project> FindByIdOrDescription(string search) 
    { 
     int projectID; 
     bool isID = int.TryParse(search, out projectID); 

     IQueryable<Project> projects; 

     if (isID) 
     { 
      projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search) || p.ProjectID == projectID); 
     } 
     else 
     { 
      projects = dataContext.Projects.Where(p => p.ProjectDescription.Contains(search)); 
     } 

     return projects; 
    } 
관련 문제