2017-08-10 96 views
-1

这是我的查询返回我准确的结果,我想。我想在LINQ中写这个。转换SQL查询到Linq(需要帮助写入SQL查询到LINQ)

select i.reportdate,co.naam,i.issueid,i.vrijetekst,i.lockuser,te.teamnaam, count(ie.issueid) as events, sum(ie.bestedetijd) as Tijd 
      from company co,hoofdcontracten hc,subcontracten sc,sonderhoud so,g2issues i,g2issueevents ie, g2issuestatus iss,teams te,locatie l 
      Where co.companyid = hc.companyid And 
      hc.hcontractid = sc.hcontractid and 
      so.scontractid = sc.scontractid and 
      sc.scontractid = i.scontractid and 
      i.issueid = ie.issueid and 
      so.teamid = te.teamid and 
      ie.locatieid = l.locatieid and 
      l.bezoek = 0 and 
      i.issuestatusid = iss.issuestatusid and 
      fase < 7 and 
      co.companyid <> 165 
      group by i.reportdate,co.naam,i.issueid,i.vrijetekst,i.lockuser,te.teamnaam ,i.reportdate 
      having sum(ie.bestedetijd)>123 

我想这个,但在选择子句混淆。如何在select子句和group by子句中使用聚合函数。

var myList = (from co in _context.Company 
          from hc in _context.Hoofdcontracten 
          from sc in _context.Subcontracten 
          from so in _context.Sonderhoud 
          from i in _context.G2issues 
          from ie in _context.G2issueEvents 
          from iss in _context.G2issueStatus 
          from te in _context.Teams 
          from l in _context.Locatie 
          where 
          co.CompanyId == hc.CompanyId 
          && hc.HcontractId == sc.HcontractId 
          && so.ScontractId == sc.ScontractId 
          && sc.ScontractId == i.ScontractId 
          && i.IssueId == ie.IssueId 
          && so.Teamid == te.Teamid 
          && ie.LocatieId == l.LocatieId 
          && l.Bezoek == false 
          && i.IssuestatusId == iss.IssueStatusId 
          && iss.Fase < 7 
          && co.CompanyId != 165 
          select new { }).ToList(); 

回答

1

我的!有人试图用各种难以辨认的变量名称来保存几分钟的时间,比如hc,sc,所以我就是这样,而不用担心这会花费时间来理解发生的事情。

我还没有试图完全解读你的查询,显然你认为它不需要显示你的实体框架类和它们之间的关系。

我收集的是你想要执行一个大连接,然后从连接中选择几个列。您想要将结果集合分组为具有相同报告日期,名称,issueid,...的项目组。您希望每个组中的所有项目都具有相同的项目,并且您希望组中的项目数量为

LINQ有两种类型的语法,实际上也是这样:Query syntax and Method syntax。尽管我可以阅读查询语法,但我更熟悉方法语法,所以我的答案将使用方法语法。我想你会明白发生了什么事。

我会在更小的步骤中完成它,如果需要,可以将所有步骤连接成一个。

首先你做一个大连接,之后你选择一些列。一个大的联接是写在查询语法时更容易为数不多的语句之一(见SO: LINQ method syntax for multiple left join

var bigJoin = from hc in _context.Hoofdcontracten 
       from sc in _context.Subcontracten 
       from so in _context.Sonderhoud 
       ... 
       from l in _context.Locatie 
       where 
       co.CompanyId == hc.CompanyId 
       && hc.HcontractId == sc.HcontractId 
       ... 
       && iss.Fase < 7 
       && co.CompanyId != 165 
       select new 
       { 
        hc, 
        sc, 
        so, 
        ... // etc select only items you'll use to create your end result 
       }; 

现在你已经有了一个大表的连接效果。你想这个表划分为具有相同值的组进行

{ 
    i.reportdate, 
    co.naam, 
    i.issueid, 
    i.vrijetekst, 
    i.lockuser, 
    te.teamnaam, 
} 

(顺便说一句:你在的GroupBy提到reportdate两次,我想这不是你的意思)

这种分组使用完成Enumerable.GroupBy

var groups = bigjoin.GroupBy(joinedItem => new 
    { // the items to group on: all elements in the group have the same values 
     ReportDate = i.Reportdate, 
     CompanyName = co.naam, 
     IssueId = i.issueid, 
     FreeText = i.vrijetekst, 
     LockUser = i.lockuser, 
     TeamName = te.teamnaam, 
    }); 

结果是组的集合。每个组都包含具有相同的价值为ReportDate,公司名称等原bigJoin项目共同价值观是group.Key

现在从您希望的下列项目各组:

  • 几个组中的常见值(ReportDate,CompanyName,IssueId,...)。我们从组的密钥中得到它们
  • Tijd =组中所有元素的ie.bestedeTijd的总和
  • Events =是组中所有元素的ie.IssueId的数量。由于组中的每个元素只有一个ie.IssueId,因此结果也是组中元素的数量。

从这个结果,你只希望保留那些具有Tijd> 123

所以我们会做一个新的选择的组,然后在Tijd

var result = groups.Select(group => new 
{ 
    Tijd = group.Sum(groupElement => groupElement.ie.bestedetijd), 
    Events = group.Count(), 

    // the other fields can be taken from the key 
    ReportDate = group.Key.reportdate, 
    CompanyName = group.Key.CompanyName, 
    IssueId = group.Key.Issueid, 
    FreeText = group.Key.FreeText, 
    LockUser = group.Key.LockUser, 
    TeamName = group.Key.TeamName, 
}) 
.Where(resultItem => resultItem.Tijd > 123); 
一凡