2012-01-23 7 views
1

私はC#の新人です。私の修士論文に使用する必要があります。現時点では、私は少し複雑な問題に直面しています。ManyToManyを使用したLINQ:複数の選択に基づくフィルタリング

は、私はこのような多対多の関係でデータベースを設定している:TimeToSaturateのための特定の値を事がある

Table Relay: 
- id (PK) 
- Name 
- Input 

Table ProtectionFunction: 
- id (PK) 
- ANSI 
- IEC 
- Description 

Table RelayConfig (junction table) 
- RelayID (PK) 
- ProtFuncID (PK) 
- TimeToSaturate 
- Remanence 

は、Relayは、複数の保護機能を持つことができ、それぞれにそれがあり、 Remanence。今私はフィルターを実現したい。ユーザはDataGridViewのチェックボックスを介して保護機能を選択でき、ListBoxはすべての保護機能をサポートするRelayをすべて表示する必要があります。

私はすでにプロジェクトのLINQ-to-SQLクラスを作成しています。しかし、私はフィルタリングを実現する方法がわからないので、今私は立ち往生しています。私が今までに見つけたすべてのLINQコマンドは、1つの保護機能に対してすべてRelayを与えます。

私は本当にあなたの1人が私にヒントを与えることを願っています。

+0

各 'Relay'オブジェクトは、' RelayConfig(s) 'プロパティを持っていなければなりません。これは、現在の' Relay'インスタンスに関連するProtectionFunctionだけを含む 'ProtectionFunction(s)'プロパティを持ちます。それは、あなたが生成したオブジェクトモデルで見ているものではありませんか? –

+0

@ M.Babcock - 'RelayConfig'オブジェクトには、 'RelayConfig'が結合されている単一の行を含む 'ProtectionFunction'プロパティがあります。それはコレクションではありません。 – SynXsiS

答えて

0
var ids = new int[]{ ... }; 
// if ids is null or ids.Length == 0 please return null or an empty list, 
//do not go further otherwise you'll get Relays without any function filter 

var query = Relays.AsQueryable(); 
foreach (var id in ids)  
{ 
    var tempId = id; 
    query = query.Where(r=>r.RelayConfigs.Any(rc=>rc.ProtFuncID == tempId)); 
} 
var items = query.ToList(); 

だけPredicateBuilderページでこれを見た 更新:ループの一時的な変数が同じ変数は各反復 のために捕獲された外側 変数トラップを回避するために必要な

foreachループの

+0

同じ問題がここにあります。私のコメントは、jeroenh – vI3Tz

+0

の回答を見てください。申し訳ありませんが、私はこれをもう一度試しました.IIDのLAST IDに対応する保護機能をサポートするすべてのリレーが選択されているようです。だから私に適切なリレーを与えてはならないIDの配列を使用すると、前に述べたものが私に与えられます。 – vI3Tz

+0

アップデートを確認してください –

0
// Build a list of protection function ids from your checkbox list 
var protFuncIDs = [1,2,3,4]; 

using(var dc = new MyDataContext()) 
{ 
    var result = dc.Relays.Where(r=>protFuncIDs.Join(r.RelayConfigs, pf=>pf, rc=>rc.ProtFuncID, (pf,rc)=>pf).Count() == protFuncIDs.Length).ToArray(); 
} 

これは特に効率的ではありませんが、それはあなたのためのトリックを行う必要があります。

+0

これは本当に速かった!ありがとうございました。しかし、不幸にも私は間違いを起こしています。私はvar protFuncIDs = [1,2,3,4]を変更しなければならなかった。 〜int [] protFuncIDs = {1、2、3、4};最初にエラーがあったためです。コードを実行すると、LINQコマンドからNotSupportedExeptionが取得されます。何か不足していますか? – vI3Tz

0

RelayConfigsから始める方が簡単です。

var protFuncIds = new[]{1,2,3}; 
var query = from rc in db.RelayConfigs 
      where protFuncIds.Contains(rc.ProtFuncID) 
      select rc.Relay; 
var relays = query.Distinct().ToList(); 

UPDATE:この動作するはずのような何か あなたのコメントに基づいて、次は動作するはずです、しかし、生成されたSQLを監視しない...

IQueryable<Relay> query = db.Relays 

foreach (var id in ids) 
    query = relays.Where(r => r.RelayConfigs.Select(x => x.ProtFuncId).Contains(id)); 

var relays = query.ToList(); 
+0

さて、ここでは、すべてのリレーが保護機能1または2または3またはそれの任意の組み合わせを持つものが選択されるという問題があると思います。私が探しているのは、保護機能1と2と3をサポートするリレーだけです。 – vI3Tz

+0

@ vl3Tz私の編集を参照してください – jeroenh

0

私はLightSwitchの中でこれを行っている、とここに私の前処理クエリがありました:

partial void UnusedContactTypesByContact_PreprocessQuery(int? ContactID, ref IQueryable<ContactType> query) 
    { 
     query = from contactType in query 
       where !contactType.ContactToContactTypes.Any(c => c.Contact.Id == ContactID) 
       select contactType; 
    } 

希望するものがあります。

関連する問題