2009-05-21 4 views
3

상황과 일치하는 하위 항목을 포함하는 항목의 목록을 검색 할 필요 :다른 목록과

나는 특정 기술을 가진 일부 사람들이 있고 그들이/하나 개 이상의 영역에 속할 수 있습니다. 스킬이 별도의 테이블에 링크되어 있으므로 해당 영역이 있습니다.

각 스킬에서 일치하는 모든 사람을 선택하는 사람들 목록을 얻고 목록에 추가하여 Distinct()를 사용하여 두 번 나타나지 않도록합니다. 위격의

결과 목록 :에

List<Person> peopleWithRightSkills 

각 [사람] 오브젝트 나는 적어도 1 주소 링크,하지만 그들은 [사람]에 관련하여 그와 같은 이상을 가질 수

내가 비교하고 그 peopl를 필터링해야 이제

List<PostalCode> acceptedPostalcodes 

:

나는 또 다른 목록을 가지고 주소의 우편 번호가 acceptedPostalcodes 내에 주소를 가지고 eWithRightSkills

나는 람다 표현식, 다른 솔루션 중 SelectMany를 조사하고, 그러나 지금, 나는 내가 믿는 하나 개의 옵션이 있습니다 일을하는 "구식", 즉 각 사람을 돌보고 각 사람마다 우편 주소 목록과 주소 목록을 일치시킵니다. 각 경기 다음에 이것을 추가 :

List<Person> matchedPeople 

표 개요 (shortend 아래에 필요한 세부 사항)

[Table:Person] 
int:ID (primary) 
string:FirstName 
string:LastName 

[Table:Address] 
int:Person_ID (foreign key to Person) 
int:PostalCode_ID (foreing key to PostalCode) 
string:StreetName 

[Table:PostalCode] 
int:ID 
string:CityName 

나는이 문제를 볼 때, 그 다만 "짧은 목록 홍보 사람입니다. "(최소 1 개, 아마도 최대 10 개의 주소)이 주소 목록을 각 사람의"유효한 우편 번호 목록 "과 비교해야합니다.

저는 지금 몇 시간 동안 갇혀 있었으므로 이보다 더 멋진 성능과 적은 성능을 해결하기 위해 어떤 구문을 사용해야하는지 알아 내려고했습니다.

답변

4
List<int> peopleIDs = peopleWithRightSkills.Select(p => p.ID).ToList(); 
List<int> postalIDs = acceptedPostalCodes.Select(c => c.ID).ToList(); 

var query = db.Persons 
    .Where(p => peopleIDs.Contains(p.ID) 
    .Where(p => p.Addresses.Any(a => postalIDs.Contains(a.PostalCode_ID)) 
); 

LinqToSql이 List<int>에 각 요소를 변환합니다 : 당신은 LINQ와 함께 일을하고 관심을 보인다 때문에, 여기 당신이 acceptedPostalCodes이 peopleWithRightSkills에서 요소를 골라 줄 방법 매개 변수 그런 다음 Contains 메서드 호출을 TSql IN 절로 변환합니다.

LinqToSql은 매개 변수 (나는 50k를 직접 보았습니다), ,과 같이 많은 요소를 행복하게 번역 할 것입니다. SqlServer는 ~ 2000 매개 변수 만 허용합니다. 목록에 더 많은 요소가 포함되어 있다면 그 목록을 해체해야합니다. 스킬이 1500 명이고 포털 코드가 1000 명인 경우 SQL Server에 2500 개의 매개 변수를 보내야하는데 400 개가 너무 많아 SqlException이 발생합니다.

+0

실제로 LINQ-to-SQL을 사용하고 있고 클라이언트에서 작업중인 모든 것을 이미 가지고 있지 않은 경우 올바른 방법입니다. – mquander

+0

그래,이 점은 결코 주소를로드하지 않고 도망 가기위한 것입니다. –

+0

나는 완전히 여기 뉴비를 느낀다. : o)하지만 고마워, 나도 이걸로 갈거야. 나는 당신이 매개 변수로 마지막 문장의 의미가 무엇인지 확신하지 못합니다. 그것에 대해 자세히 설명해 주시겠습니까? – BerggreenDK

2

사람들이 많다고 가정하면 acceptedPostalCodes은 목록이 아니어야합니다. 얼마나 많은 코드가 있는지에 따라 정렬 된 목록/2 진 트리 또는 해시 테이블 중 하나 여야합니다. 그것은 그 자체로 당신에게 크기의 성능 향상을 제공하기에 충분해야합니다. 그렇다면, 각자 사람의 주소가 acceptedPostalCodes 인 경우 해당 사람을 확인하십시오.

는 이상한 데이터가 없다면 (동일 주소가 반복해서 나타날 경우 즉, 당신은 보조 구조의 어떤 종류에 해당 주소에 대한 결과를 캐시 할 수있다.) 정말이 일을 더 나은 방법이 아니다

나는 테이블 구조를 제시함으로써 나머지 질문에서 무엇을 얻고 있는지 정말로 이해하지 못한다. 그래서 나는 네가하는 일에 약간의 미묘함을 놓치지 않기를 바란다.

편집 :

var matchedPeople = 
peopleWithRightSkills.Where(p => acceptablePostalCodes.Contains(p.Address)); 
+0

.Contains 또는 .SelectMany로 무언가를 기대하고 있었습니까? 정말이 접근법에 대한 해결책이 없습니까? – BerggreenDK

+1

물론, 루프를 수행하는 대신 acceptedPostalCodes.Contains (주소)를 사용할 수 있습니다. 성능에 영향을 미치지는 않을 것입니다. – mquander

+0

감사합니다. 작동하는지 확인하십시오. 계속 지켜봐! – BerggreenDK

관련 문제