遍历数据集以检查条件

时间:2013-03-28 19:48:43

标签: c# asp.net-mvc linq entity-framework

我为标题道歉,因为我想不出一个简洁的方式来表达我的问题。如果有人有更好的描述,请编辑它。

循环(数据库表)

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)
    }

非常感谢有关如何检查最新拒绝和当前步骤之间行的任何输入。

编辑:

我认为可以将上面的两个查询合并到一个包含PartNoCurrentStepRejectedStep的表中。从这里开始,我可以重新加入循环,这将为我提供从当前步骤到被拒绝步骤的所有行。

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

COULD 使用foreach循环来检查每个组中的组是否相同,但我更愿意使用LINQ以便处理发生在数据库端。我如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

我仍然可能不理解你的要求。您在业务说明中说过,您只想返回GroupPartNo相同的行,但您的代码示例似乎都没有考虑到这一点。这个查询并不漂亮,但它有效:

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()) 
    };

针对您的样本集运行时,它会返回: result set


<强>更新

这是另一个刺痛。此查询将排除在被拒绝的步骤(group)与当前步骤(r)之间的任何位置更改c列的情况:

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
    }