【问题标题】:LINQ left join with only the row having maximum value of a columnLINQ左连接只有具有最大值的行
【发布时间】:2015-06-03 07:45:53
【问题描述】:

我有一个表 ProjectInformation 作为(左表)

ProjectID int
{fields}

另一个表,ProjectUpdates(右表)。此表有多个记录,每月添加 1 个 ProjectID。

ProjectID int
CreateDate date
{other fields that have records}

它们的关系是 1-M。 样本数据

ProjectInformation
{ ProjectID = 1, DataA = "ABC"}
{ ProjectID = 2, DataA = "DEF"}
{ ProjectID = 3, DataA = "GHI"}

ProjectUpdates
{ProjectID = 1, CreateDate = "24/2/2014", DataB = "JKL"}
{ProjectID = 1, CreateDate = "25/1/2014", DataB = "MNL"}
{ProjectID = 1, CreateDate = "23/12/2014", DataB = "PQR"}
{ProjectID = 1, CreateDate = "23/11/2014", DataB = "STU"}
{ProjectID = 2, CreateDate = "24/2/2014", DataB = "VWX"}
{ProjectID = 2, CreateDate = "24/1/2014", DataB = "YZA"}
{ProjectID = 3, CreateDate = "21/12/2014", DataB = "BCD"}
{ProjectID = 3, CreateDate = "24/11/2014", DataB = "EFG"}
{ProjectID = 3, CreateDate = "24/10/2014", DataB = "HIJ"}
{ProjectID = 3, CreateDate = "24/8/2014", DataB = "KLM"}
{ProjectID = 3, CreateDate = "24/6/2014", DataB = "NOP"}

我希望我的 LINQ 查询返回以下数据(每个项目 1 行)

条件:左表中的行将与项目中 CreateDate 值最大的右表连接。

{ProjectID = 1, CreateDate = "24/2/2014", DataA ="ABC", DataB = "JKL"}
{ProjectID = 2, CreateDate = "24/2/2014", DataA ="DEF", DataB = "VWX"}
{ProjectID = 3, CreateDate = "21/12/2014", DataA ="GHI", DataB = "BCD"}

【问题讨论】:

  • 您可能想在结果数据集中显示不同的项目 ID。顺便说一句,你试过什么吗?
  • 仅供参考:您的示例输出都具有相同的 ProjectID1。应该是1 2 & 3
  • @Jamiec 感谢您指出这一点。改变了
  • @TahaRehmanSiddiqui - 你有机会看看我的答案吗?

标签: c# sql oracle linq


【解决方案1】:

试试这个:-

var result = (from pi in projectInfo
              join pu in projectupdates
              on pi.ProjectID equals pu.ProjectID into g
              let data = g.OrderByDescending(x => DateTime.ParseExact(x.CreateDate, 
                           "dd/M/yyyy", CultureInfo.InvariantCulture)).FirstOrDefault()
              select new
              {
                  ProjectID = data.ProjectID,
                  CreatedDate = data.CreateDate,
                  DataA = pi.DataA,
                  DataB = data.DataB
               }).ToList();

Working Fiddle.

请注意,由于我使用的是FirstOrDefault,因此您需要在访问其属性之前检查数据是否不为空。

【讨论】:

    【解决方案2】:

    您可以通过多种方式做到这一点。其中一种方法是:

    var result = (from pi in projectInformations
                  join pu in projectUpdates on pi.ProjectID equals pu.ProjectID into tpu
                  from t in tpu.OrderByDescending(c => c.CreateDate).Take(1)
                  select new { pi.ProjectID, pi.DataA, t.CreateDate, t.DataB }).ToList();
    

    【讨论】:

    【解决方案3】:

    您可以使用从 ProjectInformation 到 ProjectUpdate 和 OrderByDescending/FirstOrDefault 的 one to many 关联。

    public class ProjectInformation {
      public int ProjectID { get; set; }
      public virtual ICollection<ProjectUpdate> ProjectUpdates { get; set; }
    }
    
    db.Project
      .Select(p => new {
        ProjectID = p.ProjectID,
        MostRecentProjectUpdate = p.ProjectUpdates.OrderByDescending(u => u.CreateDate).FirstOrDefault()
    });
    

    注意:如果 CreateDate 是字符串而不是数据库中的日期,则使用 OrderByDescending 可能会很棘手。

    【讨论】:

    • 无法在 LINQ to Entities 查询中构造实体或复杂类型“”。我的查询 var projects = from p in _context.PROJECTINFORMATION where p.ISACTIVE == "Y" select new PROJECTINFORMATION() { PROJECTID = p.PROJECTID, PROJECTSUMMARYUPDATES = (ICollection)p.PROJECTSUMMARYUPDATES.OrderByDescending(x => x .UPDATEFORMONTH).FirstOrDefault() };返回项目.ToList();
    猜你喜欢
    • 2019-01-17
    • 2021-09-27
    • 1970-01-01
    • 2016-11-05
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    相关资源
    最近更新 更多