如果在嵌套集合上使用SelectMany,则保留父实例

时间:2017-12-05 10:37:43

标签: c# linq

我有一个模型Person的集合:

class Person
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public string Company {get; set;}
    public IEnumerable<string> Tags {get; set;}
}

并将LINQ转换为另一个按标签分组的集合。我怎么能这样做?

到目前为止我的方法:

var result = PersonCollection
    .SelectMany(m => m.Tags)
    .GroupBy(b => b);

但这会抛弃关于此人的所有信息。

3 个答案:

答案 0 :(得分:8)

您可以使用匿名类型持久保存Person:

var result = PersonCollection
    .SelectMany(p => p.Tags.Select(t => new{ Person = p, Tag = t }))
    .GroupBy(x => x.Tag);

现在这些组仍然包含标签作为密钥和人员:

foreach (var tagPersons in result)
{
    Console.WriteLine($"Tag: {tagPersons.Key}");
    Console.Write($" all persons: {string.Join(",", tagPersons.Select(x => x.Person.LastName))}");
}

答案 1 :(得分:2)

您需要按每个标记对人进行分组。这在LINQ查询语法中看起来最好:

var groupings =
    from p in people
    from tag in p.Tags
    group p by tag into g
    select new
    {
        Tag = g.Key,
        People = g.ToList()
    };

最后一个选择仅适用于友好名称,这也可以起作用:

var gg = from p in people
         from tag in p.Tags
         group p by tag;

在幕后,这相当于@Tim Schmelter的解决方案

答案 2 :(得分:0)

当您使用RepositoryItemLookUpEdit时,您实际上只使用这些属性制作另一个对象集合。您需要在分组中包含所需的所有信息。或者你可以使用一个有意义的&#34;键&#34;在您的分组中,使用另一个查询来查找原始集合中的其余信息。像。的东西。

GroupBy()

    var fullObject = collection.ElementAt(GroupingIndex);

这里的约束是你需要一个索引或一些硬编码值来搜索集合。

因为您按 var fullObject = collection.Where(search => search.prop1 = "foo" && search.prop2 = "bar"); 分组,更好的解决方案是将此匿名对象移动到b => b。然后你有一个对象,你可以直接在一个单独的搜索中解决。

POCO

然后,您可以在某种形式或循环或索引等中使用该分组结果集合,并从中获得您想要的内容。然后使用它从原始集合中获取您想要的内容(更多信息的位置)。

我知道答案很糟糕。

相关问题