将SQL查询转换为Linq(需要帮助将sql查询写入linq)

时间:2017-08-10 06:52:28

标签: sql linq

这是我的查询返回我想要的准确结果。我想在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子句中感到困惑。如何在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 个答案:

答案 0 :(得分:1)

我的!有人试图使用各种不可解密的变量名称(如hc,sc,so,i,即iss)来节省几分钟的打字时间,而不必担心这会花费十倍于理解所发生情况的时间。

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

我收集的是您想要执行大型连接,然后从连接中选择多个列。您希望将生成的集合分组为具有相同reportdate,name,issueid的项目组....您希望bestede tijd对每个组中的所有项目,并且您希望组中的项目数

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中提到过两次报告,我想那并不是你的意思)

此分组使用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,
    });

结果是一组群组。每个组包含原始bigJoin项目,这些项目具有相同的ReportDate,CompanyName等值。此常见值在group.Key

现在,您需要以下各项:

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

从这个结果中,你只想保留那些带有Tijd&gt;的人。 123

因此,我们将对这些群组进行新选择,然后选择Where on 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);