Linq join和group by
我正试图用linq编写以下PLSQL查询,但我在组中遇到了一些问题:Linq join和group by,linq,group-by,Linq,Group By,我正试图用linq编写以下PLSQL查询,但我在组中遇到了一些问题: select sub.EmpID, Min(sub.Stage1) Stage1, Min(sub.Stage2) Stage2, Min(sub.Stage3) Stage3, Min(sub.Prob1) Prob1, Min(sub.Prob2) Prob2 from (select det.det_numbera EmpID, case when apr.apr_performa = '1' th
select
sub.EmpID,
Min(sub.Stage1) Stage1,
Min(sub.Stage2) Stage2,
Min(sub.Stage3) Stage3,
Min(sub.Prob1) Prob1,
Min(sub.Prob2) Prob2
from
(select
det.det_numbera EmpID,
case when apr.apr_performa = '1'
then max(apr.apr_datec)
else null
end Stage1,
case when apr.apr_performa = '2'
then max(apr.apr_datec)
else null
end Stage2,
case when apr.apr_performa = '3'
then max(apr.apr_datec)
else null
end Stage3,
case when apr.apr_performa = '5'
then max(apr.apr_datec)
else null
end Prob1,
case when apr.apr_performa = '6'
then max(apr.apr_datec)
else null
end Prob2
from emdet det
left outer join emapr apr
on det.det_numbera = apr.det_numbera
group by det.det_numbera, apr.apr_performa) sub
group by sub.Empid
我已设法部分执行子查询,但在外部查询正常工作之前,分组未成功:
public List<ComplianceDetails> MyComplianceDetails(List<JobDetail> staff, List<Compliance> compliance)
{
List<ComplianceDetails> compdet =
(from s in staff
join c in compliance on s.EmpID equals c.EmpId into staffcomp
from sc in staffcomp.DefaultIfEmpty()
group s by new { s.EmpID, sc.Stage } into grp
select new ComplianceDetails(
s.EmpID,
s.Position,
s.Department,
s.Division,
s.Contract,
s.ContService,
s.Probation,
s.Sessional,
s.Teaching,
sc.Stage == "1" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null,
sc.Stage == "2" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null,
sc.Stage == "3" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null,
sc.Stage == "5" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null,
sc.Stage == "6" ? staffcomp.Max(a => a.LastDate) : (DateTime?)null
)
).ToList();
return compdet;
}
公开列出MyComplianceDetails(列出员工,列出合规性)
{
列表compdet=
(由教职员提供)
在s.EmpID上加入c.EmpID等于c.EmpID到staffcomp中
来自staffcomp.DefaultIfEmpty()中的sc
按新{s.EmpID,sc.Stage}将s分组到grp中
选择新的合规性详细信息(
s、 恩皮德,
s、 立场,,
s、 部门,
s、 分部,
s、 合同,
s、 继续服务,
s、 缓刑,
s、 会期,
s、 教学,,
sc.Stage==“1”?员工薪酬最大值(a=>a.LastDate):(DateTime?)空,
sc.Stage==“2”?员工薪酬最大值(a=>a.LastDate):(DateTime?)空,
sc.Stage==“3”?员工薪酬最大值(a=>a.LastDate):(DateTime?)空,
sc.Stage==“5”?员工薪酬最大值(a=>a.LastDate):(DateTime?)null,
sc.Stage==“6”?员工薪酬最大值(a=>a.LastDate):(日期时间?)空
)
).ToList();
返回compdet;
}
编辑//
感谢您的帮助,您指导我非常接近解决方案这似乎如预期的那样有效:
public List<ComplianceDetails> MyComplianceDetails(List<JobDetail> staff, List<Compliance> compliance)
{
string[] tQuals = new string[] { "21", "22", "23", "24" };
var compdet =
(from det in staff
join apr in compliance on det.EmpID equals apr.EmpId
into JoinedList
from apr in JoinedList.DefaultIfEmpty()
group new { det, apr } by
new
{
det.EmpID,
Stage = apr == null ? "" : apr.Stage
} into GroupedList
select GroupedList.Select(u => new
{
EmpID = u.det.EmpID,
FullName = u.det.FullName,
Position = u.det.Position,
Department = u.det.Department,
Division = u.det.Division,
Contract = u.det.Contract,
ContService = u.det.ContService,
Probation = u.det.Probation,
Sessional = u.det.Sessional,
Teaching = u.det.Teaching,
Stage1 = u.apr == null ? null : (u.apr.Stage == "1" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null),
Stage2 = u.apr == null ? null : (u.apr.Stage == "2" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null),
Stage3 = u.apr == null ? null : (u.apr.Stage == "3" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null),
Prob1 = u.apr == null ? null : (u.apr.Stage == "5" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null),
Prob2 = u.apr == null ? null : (u.apr.Stage == "6" ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null),
EduType = u.apr == null ? string.Empty : (tQuals.Contains(u.apr.Stage) ? u.apr.StageDesc : string.Empty),
EduDate = u.apr == null ? null : (tQuals.Contains(u.apr.Stage) ? GroupedList.Max(t => t.apr.LastDate) : (DateTime?)null)
})
)
.SelectMany(u => u)
.GroupBy(u => u.EmpID)
.Select(u => new ComplianceDetails
(
u.Key,
u.First().FullName,
u.First().Position,
u.First().Department,
u.First().Division,
u.First().Contract,
u.First().ContService,
u.First().Probation,
u.First().Sessional,
u.First().Teaching,
u.Where(t => t.Stage1 == u.Max(T => T.Stage1)).Select(g => g.Stage1).FirstOrDefault(),
u.Where(t => t.Stage2 == u.Max(T => T.Stage2)).Select(g => g.Stage2).FirstOrDefault(),
u.Where(t => t.Stage3 == u.Max(T => T.Stage3)).Select(g => g.Stage3).FirstOrDefault(),
u.Where(t => t.Prob1 == u.Max(T => T.Prob1)).Select(g => g.Prob1).FirstOrDefault(),
u.Where(t => t.Prob2 == u.Max(T => T.Prob2)).Select(g => g.Prob2).FirstOrDefault(),
u.Where(t => t.EduDate == u.Max(T => T.EduDate)).Select(g => g.EduType).FirstOrDefault(),
u.Where(t => t.EduDate == u.Max(T => T.EduDate)).Select(g => g.EduDate).FirstOrDefault()
))
.ToList();
return compdet;
}
公开列出MyComplianceDetails(列出员工,列出合规性)
{
字符串[]tQuals=新字符串[]{“21”、“22”、“23”、“24”};
var compdet=
(来自det in staff)
在det.EmpID等于apr.EmpID上加入apr合规性
加入联合名单
来自JoinedList.DefaultIfEmpty()中的apr
新分组{det,apr}by
新的
{
德特·恩皮德,
阶段=apr==null?“:4月阶段
}进入分组列表
选择GroupedList。选择(u=>new
{
EmpID=u.det.EmpID,
全名=u.det.FullName,
位置=u.det.位置,
部门=u.det.部门,
分部=u.det.分部,
合同=美国det合同,
ContService=u.det.ContService,
试用期=u.det.试用期,
会期=u.det.Sessional,
教学=大学教学,
Stage1=u.apr==null?null:(u.apr.Stage==“1”?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null),
Stage2=u.apr==null?null:(u.apr.Stage==“2”?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null),
Stage3=u.apr==null?null:(u.apr.Stage==“3”?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null),
Prob1=u.apr==null?null:(u.apr.Stage==“5”?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null),
Prob2=u.apr==null?null:(u.apr.Stage==“6”?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null),
EduType=u.apr==null?string.Empty:(tQuals.Contains(u.apr.Stage)?u.apr.StageDesc:string.Empty),
EduDate=u.apr==null?null:(tQuals.Contains(u.apr.Stage)?GroupedList.Max(t=>t.apr.LastDate):(DateTime?)null)
})
)
.选择多个(u=>u)
.GroupBy(u=>u.EmpID)
.选择(u=>新的合规性详细信息
(
u、 钥匙,
u、 First().FullName,
u、 第一,位置,
u、 第一部门,
u、 第一部分:,
u、 第一,合同,
u、 第一个()ContService,
u、 第一,缓刑,
u、 第一,会期,
u、 第一,教学,
u、 其中(t=>t.Stage1==u.Max(t=>t.Stage1))。选择(g=>g.Stage1)。FirstOrDefault(),
u、 其中(t=>t.Stage2==u.Max(t=>t.Stage2))。选择(g=>g.Stage2)。FirstOrDefault(),
u、 其中(t=>t.Stage3==u.Max(t=>t.Stage3))。选择(g=>g.Stage3)。FirstOrDefault(),
u、 其中(t=>t.Prob1==u.Max(t=>t.Prob1))。选择(g=>g.Prob1)。FirstOrDefault(),
u、 其中(t=>t.Prob2==u.Max(t=>t.Prob2))。选择(g=>g.Prob2)。FirstOrDefault(),
u、 其中(t=>t.EduDate==u.Max(t=>t.EduDate))。选择(g=>g.EduType)。FirstOrDefault(),
u、 其中(t=>t.EduDate==u.Max(t=>t.EduDate))。选择(g=>g.EduDate)。FirstOrDefault()
))
.ToList();
返回compdet;
}
这相当于您的tsql
的linq
,请检查:
var query = (from det in emdet
join apr in emapr on det.det_numbera equals apr.det_numbera
into JoinedList
from apr in JoinedList.DefaultIfEmpty()
group new { det, apr } by
new
{
det.det_numbera,
apr_performa = apr == null ? "" : apr.apr.apr_performa
} into GroupedList
select GroupedList.Select(u => new
{
EmpID = u.det.det_numbera,
Stage1 = u.apr == null ? null : (u.apr.apr_performa == "1" ? GroupedList.Max(t => t.apr_datec) : null),
Stage2 = u.apr == null ? null : (u.apr.apr_performa == "2" ? GroupedList.Max(t => t.apr_datec) : null),
Stage3 = u.apr == null ? null : (u.apr.apr_performa == "3" ? GroupedList.Max(t => t.apr_datec) : null),
Prob1 = u.apr == null ? null : (u.apr.apr_performa == "5" ? GroupedList.Max(t => t.apr_datec) : null),
Prob2 = u.apr == null ? null : (u.apr.apr_performa == "6" ? GroupedList.Max(t => t.apr_datec) : null)
})
)
.SelectMany(u => u)
.GroupBy(u => u.EmpID)
.Select(u => new
{
EmpID = u.Key,
Stage1 = u.Where(t => t.Stage1 != null).DefaultIfEmpty().Min(t => t.Stage1),
Stage2 = u.Where(t => t.Stage2 != null).DefaultIfEmpty().Min(t => t.Stage2),
Stage3 = u.Where(t => t.Stage3 != null).DefaultIfEmpty().Min(t => t.Stage3),
Prob1 = u.Where(t => t.Prob1 != null).DefaultIfEmpty().Min(t => t.Prob1),
Prob2 = u.Where(t => t.Prob2 != null).DefaultIfEmpty().Min(t => t.Prob2)
})
.ToList();
嗨,谢谢你的快速回复。我尝试过你的例子,但是在新的{det.det_numbera,apr.apr_performa}行中出现了错误“Object reference not set to a instance of a Object”。我可以看到det_numbera或“EmpId”有一个值,但员工可能没有stage,因此我猜stage将为null。我编辑了第一个
GroupBy
,再次检查,如果有任何问题,请告诉我。您好,谢谢您的帮助,我现在似乎更进一步了,它进入了第二个select,但得到了另一个selectt.Stage1上的行“对象引用未设置为对象的实例”:Stage1=u.Where(t=>t.Stage1!=null).DefaultIfEmpty().Min(t=>t.Stage1),看起来好像t是空的?和想法?干杯!啊!!!!,t
不能是空的,试着把t!=null
放在where
语句的第二个选择中,看看结果,这可能会解决你的null
引用,添加这个:where(t=>t!=null&&t.Stage1!=null)
Hi,刚刚尝试使用t!=null,我在相同的.Min(t=>t.Stage1)上得到了相同的错误