【问题标题】:Applying child collections to matching parents in the parent collection将子集合应用于父集合中匹配的父集合
【发布时间】:2013-07-02 17:13:05
【问题描述】:

我有一个方法可以将子集合映射到父集合中适当的父集合

 public static void ApplyParentChild<TParent, TChild, TId>(
           this IEnumerable<TParent> parents, IEnumerable<TChild> children,
           Func<TParent, TId> id, Func<TChild, TId> parentId,
           Action<TParent, TChild> action
          )
    {
        var lookup = parents.ToDictionary(id);
        foreach (var child in children)
        {
            TParent parent;
            if (lookup.TryGetValue(parentId(child), out parent))
                action(parent, child);
        }
    }

&如果我调用如下方法(项目中包含阶段列表),这将是可行的

projects.ApplyParentChild(phases, p => p.ProjectId, c => c.ProjectId, (p, c) => p.ProjectPhases.Add(c));

但我经常遇到这样一种情况,即我有一个阶段包含项目参考。所以那个时候我把它称为

phases.ApplyParentChild(projects, p => p.ProjectId, c => c.ProjectId, (p, c) => p.project=c);

这失败了。这是因为parents.ToDictionary(id) 无法获取唯一标识符并返回错误为“已添加具有相同键的项目。”

我该如何处理这个问题?我不是 linq 大师。谁能帮帮我?

【问题讨论】:

  • 您(糟糕地)重新实现 Linq 连接有什么好的理由吗?
  • HW 是 linq join 吗?

标签: c# linq collections ienumerable ilist


【解决方案1】:

由于ProjectPhases 具有一对多关系,因此您必须始终使用Project 作为父级。只需更改操作:

projects.ApplyParentChild(
    phases,
    p => p.ProjectId,
    c => c.ProjectId,
    (p, c) => c.project = p);

【讨论】:

    【解决方案2】:

    您可以使用 linq join 重申您的问题:

    var joinedData = parents
                     .Join(
                       children, 
                       parent => parent.SomeId, //id Func
                       child => child.SomeId, //parentId Func
                       (parent, child) => new{parent, child});
    foreach(var x in joinedData)
    {
        action(x.parent, x.child);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多