有没有更好的方法将子数据汇总到数据库之外的列表中?

时间:2014-04-28 17:22:08

标签: c# linq

考虑以下数据集,其中第1-3列来自父表,第4-6列来自连接子表(单个父项为零个或多个子项)。

col1 | col2 | col3 | col4 | col5 | col6
a    |  b   | c    |  1   |   2  |  3
a    |  b   | c    |  4   |   5  |  6
d    |  e   | f    |  7   |   8  |  9
g    |  h   | i    | null | null | null

如您所见,当有多个子项时,将重复父表中的数据。我无法改变我收到这种非规范化数据的事实,但我可以用我喜欢的任何格式将其发回。我想在每个父母的单个项目中使用以下两个POCO(原谅人为的名字)将其汇总:

public class ParentPoco {
    public object Col1 { get; set; }
    public object Col2 { get; set; }
    public object Col3 { get; set; }
    public List<ChildPoco> Children { get; set; }
}

public class ChildPoco {
    public object Col4 { get; set; }
    public object Col5 { get; set; }
    public object Col6 { get; set; }
}

我上面的示例数据的预期输出将是3个ParentPoco的列表。第一个列表中包含两个ChildPoco,第二个列表中包含一个ChildPoco,第三个列表中包含ChildPoco个空列表。

我的问题是:什么是最有效的高效表达,简洁的方式来汇总这些数据?通过所有父表列(见下文)进行分组,我能够得到我想要的东西,但这种方法似乎不够优雅。 感觉就像有更好的方法来做到这一点 - 也许是一种更通用的方式,只需要你指定父列一次 - 但我只是无法弄清楚是什么就是这样。

获得我想要的东西的一种方式(工作但感觉很重):

var rolledUp = from parent in myData
               group parent by new { parent.Col1, parent.Col2, parent.Col3 } into grouped
               select new ParentPoco
               {
                   Col1 = grouped.Key.Col1,
                   Col2 = grouped.Key.Col2,
                   Col3 = grouped.Key.Col3,
                   Children = grouped.Where(child => child.Col4.HasValue)
                                     .Select(child => new ChildPoco
                                     {
                                         Col4 = grouped.Key.Col4,
                                         Col5 = grouped.Key.Col5,
                                         Col6 = grouped.Key.Col6,
                                     }).ToList()
               }

1 个答案:

答案 0 :(得分:1)

  

我的问题是:汇总这些数据的最有效方法是什么?

如果您绝对需要最佳性能,那么最好不要使用Linq并根据需要进行微调。也就是说,Linq为您的代码添加了惊人的表现力,通常值得忽略不计的性能。它现在表现良好吗?如果是这样,请离开它,享受其他人可以轻松理解它的事实。如果你想知道使用Linq是否有更好的方法来做到这一点,那么我认为你当前的代码与它将会得到的一样好。

  

这种方法似乎不够优雅

对我来说很好看。我觉得这段代码试图完成的内容非常清楚,您还可以要求什么?你有可能在其他地方需要这种确切的转型吗?代码的通用版本需要知道与代码已经表达的内容一样多的东西:

myData.GroupByParent(p => new ParentPoco { Col1 = p.Col1, Col2... },
    p.Children,
    c => new ChildPoco { Col4 = c.Col4, Col5... },
    c => c.Col4.HasValue);

对我来说很难看。 也许你可以定义一个对象来保存公共属性并将其用作构造函数参数:

myData.GroupBy (x => new ParentPocoArgs { Col1 = x.Col1... })
      .Select (g => new ParentPoco(g.Key)
      {
          Children = g.Where(...
      })

真的没有给你买太多......我怀疑这些原因是为什么这个问题没有其他答案。