2010-03-03 6 views
6

Linq 쿼리에 Expression을 전달하는 것은 사용 된 구문에 따라 다르게 동작하며, 왜 그런지 궁금합니다.Linq 여기서 keyword 대 where 확장 및 표현 매개 변수

의 난이 아주 일반적인 기능을 가지고 있다고 가정 해 봅시다

private IEnumerable<Company> 
    GetCompanies(Expression<Func<Company, bool>> whereClause) 
{ 
    return (from c in _ctx.Companies.Where(whereClause) select c); 
} 

을 예상하지만 다음의 구현은 고려하지 않습니다 (위임 'System.Func'를 컴파일하지 않는 한 다음 구현이 작동
private IEnumerable<Company> 
    GetCompanies(Expression<Func<Company, bool>> whereClause) 

1 개의 인수)

private IEnumerable<Company> 
    GetCompanies(Expression<Func<Company, bool>> whereClause) 
{ 
    return (from c in _ctx.Companies where whereClause select c); 
} 

분명히 첫 번째 구문을 사용할 수는 있지만 컴파일러가 where 키워드를 Where 확장명과 동일하게 취급하지 않는 이유는 무엇입니까?

덕분에, 토마스

답변

3

에 구문을 매개 변수를 변경 (전체 문법을 단순화)되어 있습니다 일 두번째 강제로 부울 표현식이 아닙니다. 이 recitify하려면

from c in _ctx.Companies where whereClause.Compile()(c) select c; 

whereClause가 있었다 경우 Func<Company, bool> 당신이

from c in _ctx.Companies where whereClause(c) select c; 

참고

from x in e where f 

멀리 얻을 수 있다는 것을 참고로 컴파일러에 의해 기계적으로 번역되는 말을

(from x in e).Where(x => f) 

메쏘드 호출 등의 유효성을 확인하기 위해 어떠한 의미 론적 분석도하지 않고이 변환을 수행하기 때문에 기계적으로 말합니다.이 단계는 모든 쿼리 표현식이 LINQ 메소드 호출 표현식으로 변환 된 후에 나중에 제공됩니다. 특히

,

from c in _ctx.Companies where whereClause select c 

명확하게 무의미하다

_ctx.Companies.Where(c => whereClause).Select(c) 

로 변환됩니다.IEnumerable<Company>.Where가 과부하 Func<Company, bool> 수락을 가지며 Func<Company, bool>Expression<Func<Company, bool>>에서 암시 적 변환이 있으므로

from c in _ctx.Companies.Where(whereClause) select c 

합법적이라는 이유이다. 당신은 LINQ 구문을 사용하는 경우

private IEnumerable<Company> 
    GetCompanies(Expression<Func<Company, bool>> whereClause) 
{ 
    return _ctx.Companies.Where(whereClause); 
} 

where 절에있는 코드는 코드 트리를 나타내는 Expression<>,로 번역 :

+0

Expression > 대신 Func 을 인수로 사용하려면 매개 변수 유형으로 술부 을 사용할 수있었습니다. –

+0

네, 이것은 '어디'의 차이에만 초점을 맞추기위한 단순화 된 예입니다. Expression >을 사용하는 이유는 메모리에서가 아니라 데이터베이스에서 어디에서 실행해야하는지입니다. –

0

의 차이는 SQL과 같은에서이 bool로하는 평가 식을 기대하는 곳이다. 그러나 Where 메서드에서 표현식의 형식이 대리자가 될 수 있습니다.

당신이

from identifier in expression where boolean-expression select expression 

whereClausewhereClause.Compile()(c)로 변경하거나 where 절을 포함하는 쿼리 식에 대한 Func<Company, bool> whereClausewhereClause(c)

2

당신은 실제로 모든 일을 단축 할 수 있습니다. Expression<Func<Customer, bool>>을 수락하면 메서드에서 컴파일러가 C# 코드에서 변환 한 코드 트리를 사용할 수 있다고 말합니다.

이미 코드 트리가 있으므로 LINQ 구문을 사용하는 대신 Where() 메서드에 직접 전달해야합니다.

+0

네, 그 차이가 어디에서 발생하는지 예를 들어 설명했습니다. 즉, 대. 어디가. 고마워. :). –