2009-05-21 9 views
3

状況にマッチしたサブ項目を含む項目のリストを取得する必要があります。は別一覧で

私は特定のスキルを持つ一部の人を持っているし、彼らは/複数の領域に属している可能性がありますすることができます。 スキルは別のテーブルにリンクされているため、そのエリアも同じです。

各スキルで一致するすべての人物を選択し、Distinct()を使用して2回表示されないようにリストに追加することができます。人物のリスト結果の

:各[人]オブジェクト上

List<Person> peopleWithRightSkills 

を私がリンクされ、少なくとも1つのアドレスを持っていますが、彼らはその[人]

に関連して、よりを持つことができます

私は別のリストを持っている:

List<PostalCode> acceptedPostalcodes 

は今、私は、これらのpeoplを比較し、フィルタリングする必要があります住所の郵便番号がacceptedPostalcodes

内にある、私は他のソリューションの中で、SelectManyをラムダ式を調査してきたが、今、私は私があると信じてオプションを1つだけ持っているアドレスを持つeWithRightSkills物事を行う "古いスタイル"、すなわち、各人物と各人のために彼女/彼のアドレスリストを郵便番号のリストと照合すること。各試合のために、その後にこれを追加します。

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 

私は問題を見てのとおり、そのちょうど「短いリストのPR人。 "(最低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>への各要素を変換しますパラメータ。次に、Containsメソッド呼び出しをTSql IN句に変換します。

しかしのSQLServerだけ〜2000年のパラメーターを受け入れます、(私は50Kを自分で見てきた)あなたはパラメータにしたいとLinqToSqlは喜んでできるだけ多くの要素を翻訳することに注意してください。あなたのリストにそれ以上の要素が含まれている場合は、それらのリストを分割する必要があります。あなたが1500人のスキルを持ち、PostPostalCodeを1000人受け入れている場合は、SQL Serverに2500個のパラメータを送信する必要があります.SQL Serverには400個もあり、SqlExceptionが発生します。

+0

これは、実際にLINQ-to-SQLを使用していて、その上に作業しているすべてのクライアントにまだ座っていない場合に、正しい方法です。 – mquander

+0

そうですね、これは、決してアドレスをロードすることなく逃げることです。 –

+0

私はここで全く新しい初心者だと感じます。 :o)しかし、ありがとう、私もこの1つに行くだろう。私はあなたが最後の文で何を意味しているのかをパラメータで確信していません。あなたはそれについて詳述できますか? – BerggreenDK

2

多くの人がいると仮定すると、acceptedPostalCodesはリストであってはなりません。いくつのコードがあるかに応じて、ソートされたリスト/バイナリツリーまたはハッシュテーブルのいずれかでなければなりません。それだけで、あなたに桁違いのパフォーマンスの向上をもたらすのに十分なはずです。次に、ええ、それぞれの人物をチェックし、住所がacceptedPostalCodesの場合はその人物を受け入れます。

あなたは奇妙なデータを持っていない限り、(同じアドレスが何度も表示された場合、すなわち、あなたが補助的な構造のいくつかの種類にこれらのアドレスの結果をキャッシュすることができます。)、実際にこれを行うに任意のより良い方法はありません

私はテーブルの構造を提示することで、あなたが残りの質問にどのようになっているのか本当に理解していないのではないかと心配しています。

EDIT:あなたはLINQで物事を行うに興味を持っているようですので、ここであなたはacceptedPostalCodesを持ってpeopleWithRightSkillsから要素を取り出すと思います方法は次のとおりです。

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

私は.Containsまたは.SelectManyで何かを望んでいましたか?本当にこのアプローチの解決策はありませんか? – BerggreenDK

+1

もちろん、ループを実行する代わりに、acceptedPostalCodes.Contains(アドレス)を使用することができます。しかし、パフォーマンスには何の影響も与えません。 – mquander

+0

ありがとう、これが動作するかどうかをチェックする。乞うご期待! – BerggreenDK