将此SQL查询转换为Linq的最佳方法是什么?

时间:2014-04-04 19:11:17

标签: c# sql linq relational-database

我想要实现的是这个。 SiteList表中的每条记录都与Reports表中ReportCreateDate的最新记录相关联。这应该是直截了当的,但我一直在画一个空白。我该怎么做?

示例DataModule

站点列表

SiteID  SiteName    MiscData    
------------------------------------
1       Albany      New York    
2       Boston      Massachusetts   
3       Concord     New Hampshire   

报告

ReportID    SiteID  ReportCreateDate    Report Data 
-------------------------------------------------------
1           1       1/1/14 10:01 AM     alpha   
2           2       1/1/14 10:02 AM     beta    
3           3       1/1/14 10:03 AM     charlie     
4           3       1/2/14 10:01 AM     charlie     
5           1       1/2/14 10:02 AM     alpha   
6           2       1/2/14 10:03 AM     beta    
7           2       1/5/14 10:01 AM     beta    
8           3       1/5/14 10:02 AM     charlie     
9           1       1/5/14 10:03 AM     alpha   

这是一个有效的SQL查询:

select 
    sl.siteid,
    max(rr.reportcreatedate),
    rr.reprtdata 
from sitelist sl, reports rr

where sl.siteid=rr.siteid

group by sl.siteid,sl.sitename,rr.reportdata

制作此内容:

SITEID  SITENAME       MAX                  REPORTDATA
------------------------------------------------------
1       New York       1/5/2014 10:03:00 PM alpha   
2       Massachusetts  1/5/2014 10:01:00 AM beta    
3       New Hampshire  1/5/2014 10:02:00 AM charlie 

现在我需要一个Linq查询来做同样的事情。以下是我到目前为止的内容:

var results =
    (from sl in fDataModule.DataAdapter.GetTable<SITELIST>()
     join r in fDataModule.DataAdapter.GetTable<REPORTS>()
             on sl.SITEID equals r.SITEID
     group new { sl, r } by new { sl.SITEID, r.REPORTCREATEDATE, r.REPORTDATA } into rg
     select new
     {
         siteid = rg.Key.SITEID,
         rdata = rg.Key.REPORTDATA,
         //rdate = rg.OrderByDescending(x => x.r.REPORTCREATEDATE).FirstOrDefault()
         rdate = rg.Key.REPORTCREATEDATE
     })

我尝试使用orderby仅选择Reports表中的最新记录,但不返回任何记录。我缺少什么想法?

1 个答案:

答案 0 :(得分:0)

我写了一个控制台应用程序,以便向您解释您想要的内容。

最初,我宣布了以下课程:

public class SiteList
{
    public int SiteId { get; set; }
    public string SiteName { get; set; }
    public string MiscData { get; set; }
}

public class Report
{
    public int ReportId { get; set; }
    public int SiteId { get; set; }
    public DateTime ReportCreateDate { get; set; }
    public string ReportData { get; set; }
}

然后类程序包含主逻辑

public class Program
{
    static void Main(string[] args)
    {
        // Create a list of sites.
        List<SiteList> sitesList = new List<SiteList>()
        {
            new SiteList() { SiteId=1, SiteName="Albany", MiscData="New York"},
            new SiteList() { SiteId=2, SiteName="Boston", MiscData="Massachusetts"},
            new SiteList() { SiteId=3, SiteName="Concord", MiscData="New Hampshire"}
        };

        // Create a list of reports.
        List<Report> reports = new List<Report>()
        {
            new Report(){ ReportId=1, SiteId=1, ReportCreateDate = DateTime.Parse("1/1/14 10:01 AM"), ReportData="alpha"},
            new Report(){ ReportId=2, SiteId=2, ReportCreateDate = DateTime.Parse("1/1/14 10:02 AM"), ReportData="beta"},
            new Report(){ ReportId=3, SiteId=3, ReportCreateDate = DateTime.Parse("1/1/14 10:03 AM"), ReportData="charlie"},
            new Report(){ ReportId=4, SiteId=3, ReportCreateDate = DateTime.Parse("1/2/14 10:01 AM"), ReportData="charlie"},
            new Report(){ ReportId=5, SiteId=1, ReportCreateDate = DateTime.Parse("1/2/14 10:02 AM"), ReportData="alpha"},
            new Report(){ ReportId=6, SiteId=2, ReportCreateDate = DateTime.Parse("1/2/14 10:03 AM"), ReportData="beta"},
            new Report(){ ReportId=7, SiteId=2, ReportCreateDate = DateTime.Parse("1/5/14 10:01 AM"), ReportData="beta"},
            new Report(){ ReportId=8, SiteId=3, ReportCreateDate = DateTime.Parse("1/5/14 10:02 AM"), ReportData="charlie"},
            new Report(){ ReportId=9, SiteId=1, ReportCreateDate = DateTime.Parse("1/5/14 10:03 AM"), ReportData="alpha "}
        };

        // Here is the query you want

        var results = (from r in reports
                       group r by r.SiteId into g
                       join s in sitesList
                       on g.Key equals s.SiteId
                       select new
                       {
                           SiteId=s.SiteId,
                           SiteName = s.MiscData,
                           Date = g.Max(x=>x.ReportCreateDate),
                           ReportData = g.Select(x=>x.ReportData).First()
                       }).ToList();

        Console.ReadKey();
    }
}

注意在您的情况下,fDataModule.DataAdapter.GetTable<SITELIST>()是我在上面使用的siteList和fDataModule.DataAdapter.GetTable()我们reports。此外,你必须注意我使用的一些不同的变量。例如,您使用SiteID,我使用SiteId。如果进行此更改,则查询将生成所需的结果。

Here是一个.net小提琴,你可以看到提供的解决方案有效。