【问题标题】:LINQ expression to get child records with unique parentLINQ 表达式以获取具有唯一父项的子记录
【发布时间】:2014-04-24 22:00:13
【问题描述】:

这是我的域的简化版本:

class Document
{
    int id {get;set;}
    string name {get;set;}
    List<Version> Version {get;set;}
}

class Version
{
    int id {get;set;}
    string name {get;set;}
    List<VersionActivity> VersionActivity {get;set;}
    [ForeignKey]
    int DocumentID {get;set;}
}

class VersionActivity
{
    int id {get;set;}
    DateTime DateOfActivity {get;set;}
    string ActivityName {get;set;}
    [ForeignKey]
    int VersionID {get;set;}
}

查找返回最新 20 个版本的 LINQ 查询,但不能有重复的文档。

例子:

  • 我有 3 个文档,ID 分别为 1、2 和 3。
  • 我昨天编辑(即有活动)文档 1 的版本 10、20 和 30
  • 今天我编辑了文档 2 的 40、50 和 60 版(因此这些文档版本位于最近编辑的文档列表的顶部)。
  • 查询只需返回文档 2 中的最新文档版本作为记录 1,然后返回文档 1 的最新文档版本作为记录 2。

我只想到数据库进行一次往返。如果使用 SQL 更容易,我可以使用它,但我更喜欢 LINQ 查询。

谢谢。

【问题讨论】:

  • 你的例子最后一点表示查询结果中有两个版本的Document 2?
  • 我的示例中有一个错字,我已修复。我更改了要点 3 以引用文档 2。基本上,我想要最近编辑的文档版本——但如果该列表中有多个文档版本具有相同的父(文档),我想排除除第一个文档版本。
  • 因此,如果您有 50 个文档,每个文档在过去 5 分钟内都被编辑了两次,您只想要不同文档的最新更新版本吗? (抱歉,您在示例中只使用了 2 个文档,这让我有点困惑。)
  • 是的,完全正确。

标签: c# sql linq


【解决方案1】:

我认为您的问题可以更改为“按更新日期的后代顺序列出前 20 个文档”。这是查询

from d in documents
let latestVersion = (from v in d.Version
                    let latestDate = v.VersionActivity.OrderByDescending (va => va.DateTime).Select(va => va.DateOfActivity).First()
                    orderby latestDate descending 
                    select {Version = v, LatestDate = latestDate}).First()
select new {Document = d, Version = latestVersion};

或者如果每个文档的所有版本号都是递增的,只需查询

from d in document
let latestVersion = d.Version.OrderByDescending(v => v.Id).First()
select new {Document = d, Version = latestVersion};

【讨论】:

  • 我在第一个示例中遇到编译错误 (va => va.DateTime) 不起作用 - 如果应该读取 va.DateTimeOfActivity,则以下第一个函数无法编译.我尝试了不同的东西,因为我有点看到你要去哪里,但我在 LINQ 语法上遇到了很大的困难
  • 我的错。更新了第一种方法。
  • 仍然无法正常工作...我稍微修改了您的代码,因为 VersionActivity 没有 DateTime 字段...编译错误按子句顺序出现
  • 只需将 order by 更改为 orderby。我的错。
  • 是的,我修复了这个问题,但是后面的整个 select 语句无法编译。
【解决方案2】:
//GET parent IDS  
var hiringStageIds = dbContext.JobRequisitionHiringStageSubStageLink.
                 Where(x => x.RequisitionTemplateID == RequisitionTemplatedId).Select(f =>
                 f.HiringStageID
            ).Distinct().ToList();


  var workflowIds = dbContext.JobRequisitionHiringStageSubStageLink.Where(d => hiringStageIds.Contains(d.HiringStageID)).Select(f => new
                { f.HiringStageID,
                    child =new { childs=                    dbContext.JobRequisitionHiringStageSubStageLink.Where(m=>m.HiringStageID==f.HiringStageID).Select(s=>s.HiringStagesWorkflowID).ToList()
                }
                }).GroupBy(x => x.HiringStageID).Select(y => y.First());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 2021-06-16
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多