【问题标题】:Linq grouping into listLinq 分组到列表中
【发布时间】:2017-03-03 12:13:02
【问题描述】:

我在 linq 中有以下选择查询:

var something = 
    from te in taskEvidences
    join e in evidences on te.EvidenceId equals e.Id
    join tr in taskRequirements on te.TaskListId equals tr.TaskListId
    join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
    select new
    {
        Evidence = e,
        RequirementIndices = r.Index
    };

目前它选择了一个 Evidence 对象以及几个 Index (int) 值,因此例如我可能会返回 5 条记录,它们都具有相同的 Evidence 对象和 5 个不同的索引。

我想要做的只是返回带有证据对象的单个记录和索引的List<int>。我尝试使用分组,但我不断收到关于无法从使用中推断出类型的错误。这是一种这样的尝试:

group new {e, r} by new {e}
into g
select new
{
    Evidence = g.Key,
    RequirementIndices = g.SelectMany(x => x.r.Index)
};

错误发生在分配给 RequirementIndices 属性的 SelectMany 周围。我尝试了几个我在网上找到的建议,但没有一个有帮助。我认为这是我的一个小错误,但我现在要瞎写代码了!

更新:

确切的错误:

无法从用法中推断方法“Enumerable.SelectMany(IEnumerable, Func>)”的类型参数。尝试明确指定类型参数。

【问题讨论】:

  • 那么确切的错误是什么? minimal reproducible example 会更容易为您提供帮助。
  • SelectMany 是扁平化列表列表。连接表不会将列表嵌套到列表中。如果你把它改成Select呢?顺便说一句,r 似乎是分组的一部分。
  • @JonSkeet 我已经用确切的错误更新了问题。
  • @JeroenvanLangen 你说得对,我只需要Select 而不是SelectMany!告诉过你我要瞎写代码了!

标签: c# linq


【解决方案1】:

正如@JeroenvanLangen 在对我的问题的评论中所建议的那样,我不需要SelectMany 只需要Select

var something = 
    from te in taskEvidences
    join e in evidences on te.EvidenceId equals e.Id
    join tr in taskRequirements on te.TaskListId equals tr.TaskListId
    join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
    group new { e, r } by new { e }
    into g
    select new
    {
        Evidence = g.Key,
        RequirementIndices = g.Select(x => x.r.Index).ToList()
    };

【讨论】:

    【解决方案2】:

    您应该能够通过避免顶层连接来产生相同的分组结果:

    var something = 
        from te in taskEvidences
        join e in evidences on te.EvidenceId equals e.Id
        select new
        {
            Evidence = e,
            RequirementIndices = (
                from tr in taskRequirements
                join r in newSelectableModule.Requirements on tr.RequirementListId equals r.Requirement.Id
                where te.TaskListId equals tr.TaskListId
                select r.Index
            ).ToList()
        };
    

    现在列表是通过关联子查询和连接来选择的,这消除了父记录“重复”的创建。它应该具有与原始查询相同的性能。

    【讨论】:

      猜你喜欢
      • 2013-11-27
      • 2013-12-20
      • 2012-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      相关资源
      最近更新 更多