2013-02-20 2 views
1

LinqPad를 사용하여 기본 동적 Linq 쿼리를 작성하려고합니다. 내 방법은 사용자에게 1 - 3 옵션을 선택하도록 요청한 다음 입력에 따라 동적으로 쿼리를 작성합니다.Dynamic Linq 쿼리가 예상대로 작동하지 않습니다. 무엇이 잘못 되었습니까?

public void FilteredPropertySearch() 
{ 
    bool addAnotherOption = true; 
    int option; 
    Dictionary<int, bool> parameters = new Dictionary<int, bool>(); 
    var predicate = PredicateBuilder.False<ResidentialProperty>(); 

    Console.WriteLine("Follow instructions to filter property search results"); 

do 
{ 
    // get user input 

    option = int.Parse(Console.ReadLine()); 

    switch(option) 
    { 
     case 1: 
      parameters.Add(1, true); 
      break; 

    // more cases - when case 0 addAnotherOption = false, loop ends 

     default: 
      Console.WriteLine("That was not a valid option"); 
      break; 
    } 

}while(addAnotherOption == true); 

    foreach(KeyValuePair<int, bool> p in parameters) 
{ 
    if(p.Key == 1 && p.Value == true) 
     predicate = predicate.Or (c => c.HasBackGarden); 
    if(p.Key == 2 && p.Value == true) 
     predicate = predicate.Or (c => c.HasFrontGarden); 
    if(p.Key == 3 && p.Value == true) 
     predicate = predicate.Or (c => c.HasSecureParking); 
} 

ResidentialProperties.Where (predicate).Dump(); 

} 

foreach 루프는 사용자의 입력을 기반으로 쿼리를 작성해야하지만, 예를 들어, 나는 사실 사전에서 첫 번째 값을 더 다른 사람을 선택하면, 어떤 결과를 반환하지 않습니다. 그것은 분명히 내 데이터베이스 테이블에 Key(1)을 만족시키는 값이 있다는 것을 알고 있어야합니다.

if이 표시된 후에 다른 항목을 수행해야합니까?

편집

내가 대신 술어 빌더를 사용했습니다 그리고 내가 (편집 코드에 따라) predicate.Or를 사용할 때 작업 (가지) 것 같다,하지만 그것은 단지 내가 선택한 첫 번째 옵션을 반환 표현 트리를 만드는 것이 아닙니다. predicate.Orpredicate.And으로 변경하면 선택한 각 사용자 입력을 필터 표현식에 추가했을 것입니다.

사용자가 세 가지 옵션을 모두 선택한 경우 HasBackGarden, HasFrontGarden 및 HasSecureParking 열이 true 인 행만 반환됩니다. 어떻게해야합니까?

+1

여기서'Enumerable.Empty <>'로 할당 된'query' 만 볼 수 있습니다 (즉, 여러분의 타입의 빈리스트). 필터링하고있는 데이터와 어떻게 연결하고 있습니까? –

+0

'var query; '를 사용할 수 없어서 그랬습니다. Linqpad에서는 ResidentialProperty라는 모델에 매핑되는 ResidentialProperties라는 테이블을 쿼리합니다. select와 같이'query'를 사용하여 무언가를해야합니까? – MattSull

답변

3

, 당신은 대신 .Or.And를 사용하는 것이 정확하지만, 그렇게하기 위해서는, 당신은 PredicateBuilder.True<ResidentialProperty>()로 시작해야 False 대신.

필터를 추가하기 전에 올바른 결과 집합에 모든 레코드가 포함되어 있으며 이후의 각 필터가 결과 집합을 제한하기 때문입니다. False으로 시작하면 레코드 중 어 @ 것도 술어를 만족시킬 수 없습니다.

+0

훌륭합니다. 고마워. – MattSull

1

코드에서 빈 열거 형 변수 인 "쿼리"에서 작동하는 것처럼 보입니다. 기억해 두어야 할 것은 쿼리를 호출 한 것이 데이터 집합이고 Where 문은 해당 데이터 집합의 쿼리입니다. 따라서 첫 번째 쿼리는 빈 데이터 집합에 있으며 foreach에서 추가 쿼리를 실행하면 빈 집합을 수정하는 것처럼 보입니다.

또한 bool이기 때문에 .Where (q => q.HasWhatever) 할 수 있습니다. 당신이 당신의 결과는 조건 모든을 만족하는 레코드로 설정 제한하려면

+0

먼저 가능한 모든 행으로 쿼리를 채워야합니까? 실적에 나쁜 영향을 미치지 않겠습니까? – MattSull

+0

해당 변수는 일반적으로 "채워진"데이터 집합이 아니고 데이터 소스를 가리키는 DbSet 또는 일부 열거 형입니다. 엔터티 프레임 워크 또는 무언가를 사용하면 쿼리가 실제로 발생할 때까지 채워지지 않을 데이터베이스 백업 컬렉션이 컬렉션이됩니다. – Thabo

+0

EF를 사용 중이라고 가정 할 때 포함하는 데이터베이스에 매핑되는 DBContext에 여기에서 의도 한대로 쿼리 할 수있는 DbSet 가 있어야합니다. – Thabo

관련 문제