2011-03-21 2 views
4

여러 데이터베이스로 책 데이터베이스를 검색하고 싶습니다. 더 많은 키워드를 제공할수록 검색 범위가 좁아집니다. 검색이 사실 좁은 I가 제공하는 키워드를하지 않습니다,SQLite 및 Linq이 예상 결과를 제공하지 않는 Queryable.Intersect()

var words = text.Split(' '); 

IQueryable<Reference> query = null; 

foreach (string word in words) 
{ 
    var result = from r in _dbConnection.GetTable<Reference>() 
       where r.Title.Contains(word) 
       || r.ReferenceAuthor.Any(a => a.Person.LastName.Contains(word) || a.Person.FirstName.Contains(word)) 
       || r.ReferenceCategory.Any(c => c.Category.Name.Contains(word)) 
       || r.ReferenceKeyword.Any(k => k.Keyword.Name.Contains(word)) 
       orderby r.Title 
       select r; 

    query = query == null ? result : query.Intersect(result); 
} 

query.OrderBy(r => r.Title); 

문제는 : 여기 내 코드입니다. 검색 결과는 키워드를 제공하는 순서에 따라 다릅니다. 또한 두 개 이상의 키워드가 관련되어 있으면 마지막 OrderBy() 호출이 안정적으로 작동하지 않습니다. 내 아이디어가 결함인가, 구현 방법인가?

+0

저는 System.Data.SQLite.SQLiteConnection과 System.Data.Linq.DataContext를 사용하고 있습니다. –

답변

5

사용자가 closing over the word이고 변수가 access to modified closure입니다.

루프를 반복 할 때마다 words 컬렉션의 문자열 값을 변수 word으로 캡처합니다. 그러나 LINQ는 지연된 실행을 사용하며 루프가 완료 될 때까지 쿼리가 실행되지 않습니다.이 시점에서 동일한 단어 변수가 쿼리의 모든 인스턴스에서 캡처됩니다. 따라서 검색 키워드의 순서에 따라 결과가 달라집니다 .

이 문제를 해결하려면 루프를 반복 할 때마다 변수의 로컬 복사본을 가져옵니다.

foreach (string w in words) 
{ 
    string word = w; 
    ... 
+0

또 다른 해결 방법은 각 반복마다 ToArray()를 호출하는 것입니다. 그러나 실적이 저하 될 수 있습니다. –

+1

귀하가 진술하신 바로 그 이유로 '해결 방법'을 권장하지 않습니다. 문제를 숨기고 코드가 단순히 확장되지 않는다는 것을 의미합니다. 누군가가 나중에 성능 문제를 해결하고 * 실수 *하여 현재 버그를 다시 소개 할 수 있습니다. –

+0

아하, 정확하게 그럴 것 같습니다. 감사! –

관련 문제