2016-10-31 6 views
1

ここに私がやろうとしていることがあります:どうすればこのLINQクエリを書くのですか

私は一連のレコードを持っています。記録は年ごとに並べられます。

Record 
{ 
    string Name {get;set;}, 
    int Year {get;set;} 
    //some other properties 
} 

私は各レコードに対して実行される一連のルールを持っています。各ルールにはタイプと条件があります。

Rule 
{ 
    RuleType Type {get;set;}, 
    Func<Record,bool> Condition {get;set;} 
} 

与えられたルールタイプでは、レコードのリストを繰り返してルール条件が満たされた最初のものを探したいと思います。私はこれをすべてのルールタイプに対して実行したい。

私はSQLでこれを書いていた場合、私は何かLINQで

SELECT Type, MIN(Year) 
FROM Records, Rules 
WHERE Rules.Condition(Records) = TRUE 
GROUP BY Type 

それを書くかもしれませんが、私は正しく一緒デカルトを置くのに苦労しています+シングルWHERE条件+最初に発生+グループに参加します。

助けてください。

ありがとうございました。あなたはこのような二重のfromを使用してLINQクエリ構文でデカルト積を行うことができます

+0

「レコード」と「ルール」の関係は何ですか?あなたは例リストを提供できますか? – PoweredByOrange

+0

サンプル情報とサンプル結果を表示することが理想的です。あなたはグループごとに最初の出現を望みますか? –

答えて

0

var query= from r in Records 
      from rule in Rules 
      where rule.Condition(r) 
      group new {rule.Type, r.Year } by rule.Type into g 
      select g.OrderBy(e=>e.Year).FirstOrDefault(); 
+0

'r.Type'ではなく' rule.Type'を意味しています。 – juharr

+0

右、それを固定する、ありがとう@juharr – octavioccl

+2

お願いします、downvoter、あなたは理由を説明できますか? – octavioccl

2
/* Calculate MIN(Year) */ 
var rule = rules.First(r => r.Type == specificType); 
var result = records 
    .Where(r => rule.Condition(r)) 
    .Min(r => r.Year) 

/* or just some other rule */ 

var result = records.FirstOrDefault(r => rule.Condition(r)); 
0

ですから、二つの配列を持っています。レコードとルールの配列の配列:

IEnumerable<Record> records = ... 
IEnumerable<Rule> rules = ... 

あなたの目標のあなたのテキスト記述は、SQL文が示唆よりも少し異なっている:

与えられたルールの種類については、私は、反復処理したいですレコードのリストとルール条件が満たされた最初のレコードを検索します。私はこれをすべてのルールタイプに対して実行したい。

つまり、すべてのルールに対して、ルールに一致する最初のレコードのみが必要です。

あなたのSQLステートメントを使用すると、すべてのルールのための記録的な年で注文したルール、

あなたのテキストの要件を満たすすべてのレコードを望ん示唆しています。

すなわち
IEnumerable<Record> result = Rules.Select(rule => 
    records.Where(record => rule.Condition(record)) 
    .FirstOrDefault(); 

:ルールのシーケンス内のすべてのルールから、rule.Condition(レコード)が真であるレコードの順序で最初の(またはデフォルト)の記録を取るこれはあなたのLINQのようになるために

これはあなたの目標の説明文に正確に従いますが、すべてのレコードについて知っているレコードの結果シーケンスから、そのレコードがルールに適合するルールがあります。レコードがその条件を満たす最初のルールであるかどうかはもう分かりません。

また、あなたの結果にルールを覚えて、この最初のレコードの試合を支配しているかを知りたい場合は、次の規則のコレクション内のすべてのルールから

var result = rules.Select(rule => new 
    { 
     Rule = rule, 
     FirstMatchingRecord = records 
     .Where(record =>rule.Condition(record)) 
     .FirstOrDefault(), 
    }); 

は、ルールを選択して、コレクションの最初のレコードルールと一致するレコードを匿名オブジェクトのプロパティRuleおよびFirstMachingRecordに入れます。

最初に一致するレコードは、レコードコレクションの順番になります。

IEnumerable<Record> result = Rules.Select(rule => 
    records.Where(record => rule.Condition(record)) 
    .OrderBy(record => record.Year) 
    .FirstOrDefault(); 

レコードの数と一致するレコードの数に応じて、それは、レコード一次に賢明かもしれませんし、その後で注文した結果を使用する:あなたのSQLステートメントを使用すると、昇順年のレコードを注文したいことを示唆していますあなたの場所の文:

var orderedRecords = records.Orderby(record => record.Year); 
IEnumerable<Record> result = Rules.Select(rule => 
    orderedRecords.Where(record=> rule.Condition(record)) 
    .FirstOrDefault(); 

あなたのSQL文あなたはすべてのためにとルールのグループが年順のレコードの順序を支配したいことを示唆しています。 LINQでは:ルールのコレクション内のすべてのルールについては

var result = rules.Select(rule => new 
    { 
     Rule = rule, 
     MatchingRecords = records 
      .Where(record => rule.Condition(record)) 
      .OrderBy(record => record.Year), 
    }); 

、ルールを含む新しい匿名のオブジェクトと、昇順に年が注文したルールに一致するレコードの列を作ります。この結果から

関連する問題