Question

What I am trying to achieve is this. Each record in the SiteList table joined with the most current record by ReportCreateDate in the Reports table. This should be straight forward but I keep drawing a blank. How do I do this?

Sample DataModule

SiteList

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

Reports

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   

This is a working SQL query:

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

Produces this:

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 

Now I need a Linq query to do the same. Here is what I have so far:

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
     })

I've tried to use the orderby to select only the latest records in the Reports table but it returns no records. Any ideas what I am missing?

Was it helpful?

Solution

I wrote a console application, in order to explain you what you want.

Initially, I declared the following classes:

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

and

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

Then the class Program contains the main logic

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();
    }
}

NOTE In your case fDataModule.DataAdapter.GetTable<SITELIST>() is the siteList I used above and fDataModule.DataAdapter.GetTable() us the reports. Also you have to pay attention on some different variable I used. For instance you use SiteID and I used SiteId. If you make this changes then the query produces the results you want.

Here is a .net Fiddle, where you can see that the provided solution works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top