我为标题道歉,因为我想不出一个简洁的方式来表达我的问题。如果有人有更好的描述,请编辑它。
循环(数据库表)
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
,CurrentStep
和RejectedStep
的表中。从这里开始,我可以重新加入循环,这将为我提供从当前步骤到被拒绝步骤的所有行。
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以便处理发生在数据库端。我如何实现这一目标?
答案 0 :(得分: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
)与当前步骤(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
}