1

私の問題を簡潔に表現する方法が思いつかなかったので、タイトルについてお詫び申し上げます。誰かがより良い説明を持っている場合は、編集してください。

サイクル (データベース テーブル)

int PartNo (PK)
int StepNo
string Group
Datetime Start
Datetime Finish
string Status

PartNo  |  StepNo  |  Group  |  Start  |  Finish  |  Status
  0     |    0     | Group1  | 1-1-01  |  1-2-01  |    A
  0     |    1     | Group2  | 1-2-01  |  1-3-01  |    A
  0     |    2     | Group3  | 1-3-01  |  1-4-01  |    A
  0     |    3     | Group1  | 1-4-01  |  1-5-01  |    R
  0     |    4     | Group1  | 1-5-01  |  1-6-01  |    
  0     |    5     | Group1  | 1-6-01  |  1-7-01  |       
  0     |    6     | Group1  | 1-7-01  |          |    
  0     |    7     | Group2  |         |          |    
...more PartNo...

「ビジネス」用語で必要なものを簡単に説明することから始めましょう。このテーブルは、複数のグループによって承認されたアイテムを追跡します。例のテーブルでわかるように、グループ 1、グループ 2、およびグループ 3 がアイテムを承認し、グループ 1 に戻ります。空のステータス フィールドは、そのグループ内での再割り当てを表しており、ステップ 3 で拒否された後、数回再割り当てされていることがわかります。時間はあるstartが時間がないため、現在のステップが 6 であることもわかりますfinish。部品番号ごとに複数の不合格が発生する可能性があります。

ここで、私のトリッキーなクエリについて説明します。最近拒否されたかどうかを確認する必要があります。これは、現在のグループと同じグループで拒否が発生した場合に定義されます。Group1この場合、最近の拒否として分類されるためには、現在のステップと拒否ステップの間に含まれるグループも同じである必要があります。この例では、現在のステップは 6 であり、クエリは拒否の場所であるステップ 3 を返す必要があります。明確にするために、ステップ 4 または 5 が他のグループに変更された場合、クエリは何も返しません。それが理にかなっていることを願っています。

最後に拒否された行を返すクエリを作成できますが、現在のステップと拒否されたステップの間で行を反復処理してグループをチェックする方法がよくわかりません。

現在のステップを取得

Cycle.Where(c => c.Start.HasValue() && !c.Finish.HasValue())
    .GroupBy(c => c.PartNo)
    .Select(g => new
    {
        PartNo = g.Key,
        StepNo = g.Min(s => s.StepNo)
    }

最新の拒否を取得

Cycle.Where(c => c.Status == "R")
    .GroupBy(c => c.PartNo)
    .Select(g => new
    {
        PartNo = g.Key,
        StepNo = g.Max(s => s.StepNo)
    }

最新のリジェクトと現在のステップの間の行を確認する方法についてのご意見をお待ちしております。

編集:

PartNo上記の 2 つのクエリを、CurrentStep、およびを含む 1 つのテーブルに結合することは可能かもしれないと考えていますRejectedStep。ここから、cycle で再結合できます。これにより、現在のステップから拒否されたステップまでのすべての行が得られます。

var combined = currentStep
            .Join(rejectedStep,
                    c => c.PartNo,
                    r => r.PartNo,
                    (c,r) => new { PartNo = c.PartNo, Current = c.StepNo, Reject = r.Stepno});

結合クエリを挿入して取得しますStepNo <= Current && StepNo >= Reject

ループを使用しforeachて、これらのそれぞれのグループが同じかどうかを確認できますが、データベース側で処理が行われるように LINQ を使用することをお勧めします。どうすればこれを達成できますか?

4

1 に答える 1

1

私はまだあなたの要求を理解していないかもしれません. Groupビジネスの説明で、が と が同じ行のみを返したいとおっしゃいましたがPartNo、コード サンプルのどれもこれを考慮していないようです。このクエリはきれいではありませんが、機能します。

var results = 
    from c in Cycles
    group c by new { c.PartNo, c.Group } into g
    let c = g.Where(s => s.Start.HasValue && !s.Finish.HasValue)
             .Select(s => s.StepNo)
    let r = g.Where(s => s.Status == "R")
             .Select(s => s.StepNo)
    where r.Any() && c.Any()
    select new 
    { 
        g.Key, 
        Steps = g.Where(s => s.StepNo <= c.Max() && s.StepNo >= r.Min()) 
    };

サンプル セットに対して実行すると、以下が返されます。 結果セット


アップデート

ここに別の刺し傷があります。このクエリは、拒否されたステップ ( ) と現在のステップ ( )groupの間の任意の時点で列が変更された場合を除外します。rc

var results = 
    (from c in Cycles
    group c by c.PartNo into g
    let c = g.Where(s => s.Start.HasValue && !s.Finish.HasValue)
             .Select(s => s.StepNo)
    let r = g.Where(s => s.Status == "R")
             .Select(s => s.StepNo)
    where r.Any() && c.Any()
    let steps = g.Where(s => s.StepNo <= c.Max() && s.StepNo >= r.Min()) 
    where steps.Select(x => x.Group).Distinct().Count() == 1
    select new 
    { 
        g.Key, 
        Steps = steps
    }
于 2013-03-28T21:38:57.167 に答える