2017-07-28 51 views
-1

我正在處理一個需要做點計數和分組的問題。我試圖在工作中做到這一點,但無法在一個查詢中完成。當然,我可以把它分開並得到答案,但我很好奇,如果有人能夠幫助我在一個聲明中找到答案?一條LINQ語句,將返回答案而不會將其分解出

下面是代碼和我需要的答案。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace GetCountInfo 
{ 
    public partial class _Default : Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      /* 
      * 
      * 
      * current Date would be: 7/27/2017 4:00 PM 
      * 
      ReportOutOfDateCountDto 

      The answer would be: 

      Patrick = Count of 1 
      Stacy = Count of 2 

      */ 
     } 

     /// <summary> 
     /// This is the data for each year nbr 
     /// </summary> 
     /// <returns></returns> 
     public IList<YearNbrInfoDto> GetYearInfoData() 
     { 
      IList<YearNbrInfoDto> theData = new List<YearNbrInfoDto>(); 

      theData.Add(new YearNbrInfoDto { RecordId = 1, YearNbr = 0, CreateDt = new DateTime(2014,1,6) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 1, YearNbr = 1, CreateDt = new DateTime(2014, 5, 6) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 1, YearNbr = 2, CreateDt = new DateTime(2015, 1, 22) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 1, YearNbr = 3, CreateDt = new DateTime(2018, 5, 6) }); // NOT out of date 

      // Above would just be a count of 1 because there are 3 that are out of date, but they all have the same record id, so it would just be 1 record id 

      theData.Add(new YearNbrInfoDto { RecordId = 2, YearNbr = 0, CreateDt = new DateTime(2019, 5, 6) }); // NOT out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 2, YearNbr = 1, CreateDt = new DateTime(2018, 1, 6) }); // NOT out of date 

      // Above would not be calculated because none of the Record Ids are out of date 

      theData.Add(new YearNbrInfoDto { RecordId = 5, YearNbr = 0, CreateDt = new DateTime(2014, 3, 3) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 5, YearNbr = 1, CreateDt = new DateTime(2015, 3, 6) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 5, YearNbr = 2, CreateDt = new DateTime(2017, 10, 3) }); // NOT out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 5, YearNbr = 3, CreateDt = new DateTime(2018, 1, 6) }); // NOT out of date 

      // Above would just be a count of 1 because there are 2 that are out of date, but they all have the same record id, so it would just be 1 record id 

      theData.Add(new YearNbrInfoDto { RecordId = 6, YearNbr = 0, CreateDt = new DateTime(2014, 3, 3) }); // out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 6, YearNbr = 1, CreateDt = new DateTime(2018, 3, 6) }); // NOT out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 6, YearNbr = 2, CreateDt = new DateTime(2019, 1, 3) }); // NOT out of date 
      theData.Add(new YearNbrInfoDto { RecordId = 6, YearNbr = 3, CreateDt = new DateTime(2020, 1, 6) }); // NOT out of date 

      // Above would just be a count of 1 because there is 1 that is out of date 

      return theData; 
     } 

     /// <summary> 
     /// This ties the Year Record info to the user ids 
     /// </summary> 
     /// <returns></returns> 
     public IList<MainRecordInfoDto> GetMainRecordInfoData() 
     { 
      IList<MainRecordInfoDto> theData = new List<MainRecordInfoDto>(); 

      theData.Add(new MainRecordInfoDto { UserId = 1, RecordId = 1 }); 
      theData.Add(new MainRecordInfoDto { UserId = 1, RecordId = 2 }); 
      theData.Add(new MainRecordInfoDto { UserId = 1, RecordId = 3 }); 
      theData.Add(new MainRecordInfoDto { UserId = 1, RecordId = 4 }); 


      theData.Add(new MainRecordInfoDto { UserId = 2, RecordId = 5 }); 
      theData.Add(new MainRecordInfoDto { UserId = 2, RecordId = 6 }); 

      return theData; 
     } 

     /// <summary> 
     /// This is the main User info... 
     /// </summary> 
     /// <returns></returns> 
     public IList<UserInfoDto> GetUserInfoData() 
     { 
      IList<UserInfoDto> theData = new List<UserInfoDto>(); 

      theData.Add(new UserInfoDto { Name = "Patrick", UserId = 1 }); 
      theData.Add(new UserInfoDto { Name = "Stacy", UserId = 2 }); 

      return theData; 
     } 
    } 

    public class ReportOutOfDateCountDto 
    { 
     public string Name { get; set; } 

     /// <summary> 
     /// This would be the count of out of date PER RecordId 
     /// </summary> 
     public int CountOfOutOfDateYearNbrs { get; set; } 

    } 

    public class YearNbrInfoDto 
    { 

     public int RecordId { get; set; } 

     public int YearNbr { get; set; } 

     public DateTime CreateDt { get; set; } 
    } 

    public class MainRecordInfoDto 
    { 
     public int UserId { get; set; } 

     public int RecordId { get; set; } 
    } 

    public class UserInfoDto 
    { 
     public string Name { get; set; } 
     public int UserId { get; set; } 
    } 
} 
+1

你能顯示你在兩次查詢中試過的代碼嗎 – Fabio

+0

不幸的是它是在工作:-( – user272727

回答

1

您可以加入相關數據更短和更高效的查詢:

var result = GetYearInfoData() 
    .Where(d => d.CreateDt < DateTime.Now) 
    .Select(x => x.RecordId)         // RecordIds 1, 1, 1, 5, 5, 6 
    .Distinct()               // RecordIds 1, 5, 6 
    .Join(GetMainRecordInfoData(), i => i, r => r.RecordId, (i, r) => r.UserId) // UserIds 1, 2, 2 
    .Join(GetUserInfoData()  , i => i, u => u.UserId , (i, u) => u.Name ) // Names { Patrick, Stacy, Stacy } 
    .GroupBy(n => n) 
    .Select(g => new { Name = g.Key, Count = g.Count() }); // Names and Counts 

如果數據從數據庫中則不然,它可以通過創建將更加優化查詢前的查詢:

var yearLookup = GetYearInfoData().ToLookup(y => y.RecordId); 
var recordLookup = GetMainRecordInfoData().ToLookup(r => r.UserId); 

var result = GetUserInfoData().Select(u => new { u.Name, Count = recordLookup[u.UserId] 
    .Count(i => yearLookup[i.RecordId].Any(d => d.CreateDt < DateTime.Now)) }); 
+0

謝謝 - 我更喜歡你的答案! – user272727

0

所以我想我得到了答案,但真的不明白如何。請看看下面:

var tblYearInfoData = GetYearInfoData(); 

var tblMainRecordInfoData = GetMainRecordInfoData(); 

var tblGetUserInfoData = GetUserInfoData(); 

var thisWillNeverWork = (from yfd in tblYearInfoData 
         where yfd.CreateDt < DateTime.Now // Pull all the record ids where the create dt is out of date... i.e. in the past... 
         select new 
         { 
          RecordId = yfd.RecordId // Select those record ids.... 
         }) 
         .GroupBy(gb => gb.RecordId) // Now group by the record ids... so if there is one record id.... and there are 3 that are out of date... it will combine it to 1... 
         .Select(selectGroup1 => new 
         { 
          RecordId = selectGroup1.Key, // This will get the grouped by record ids... 

          // Get the User Id so then we can do a final count with the name 
          UserId = tblMainRecordInfoData.Where(w => w.RecordId == selectGroup1.Key).Select(s => s.UserId).FirstOrDefault() 
         }).GroupBy(gb => gb.UserId) // Then we group by user id.... 
          .Select(selectGroup2 => new ReportOutOfDateCountDto 
          { 
          Name = tblGetUserInfoData.Where(w => w.UserId == selectGroup2.Key).Select(s => s.Name).FirstOrDefault(), // we use the user id grouped by... to get the name 
          CountOfOutOfDateYearNbrs = selectGroup2.Count() // then we do a count on the group by and somehow it worked... haha not sure how :-) 
          }).ToList(); 
相關問題