Linq join和group by

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

我正试图用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'
  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)上得到了相同的错误