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...

让我首先用“业务”字眼简要描述我需要什么。此表跟踪一个项目,因为它已被多个组批准。正如您在示例表中看到的,group1、group2 和 group 3 批准了该项目,然后返回到 group1。空状态字段表示该组内的重新分配,您可以看到它在步骤 3 中被拒绝后被重新分配了几次。您还可以告诉当前步骤是 6,因为它有start时间,但没有finish时间。每个 PartNo 可以有多个拒绝。

现在这里是我棘手的查询的描述。我需要检查最近是否有拒绝。这是由与当前组在同一组中发生的拒绝定义的。当前步骤和拒绝步骤之间涉及的组也必须相同,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,CurrentStepRejectedStep. 从这里,我可以使用循环重新加入,这将为我提供从当前步骤到被拒绝步骤的所有行。

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 回答