如何编写一个LINQ查询,使其将分层源数据转换为反向分组?
假设我有一个Topic对象列表,每个对象都包含一组标记(Tags),这些标记表示该主题上的元数据标记。 我需要编写一个LINQ查询,以基本上颠倒层次结构,以便我拥有一个标记(Tag)列表,每个标记(Tag)都有一个包含使用该特定标记(Tag)进行标记的主题(Topic)集合。
Topic { Title = "Political Debate #1", Posted = 01/02/2008 }
Tag { Name = "Contraversial", Color = "Red" }
Tag { Name = "Politics", Color = "LightBlue" }
Topic { Title = "iPhone to support SiliverLight!", Posted = 02/23/2009 }
Tag { Name = "BleedingEdge", Color = "LightBlue" }
Tag { Name = "Contraversial", Color = "Red" }
Tag { Name = ".NET", Color = "LightGreen" }
Topic { Title = "Fed Chairman admits guilt for causing second Great Depression", Posted = 06/15/2010 }
Tag { Name = "Politics", Color = "LightBlue" }
Tag { Name = "Contraversial", Color = "Red" }
我希望上述数据的展示效果与下面的结果类似。
Tag { Name = "Contraversial", Color = "Red" }
Topic { Title = "Political Debate #1", Posted = 01/02/2008 }
Topic { Title = "iPhone to support SiliverLight!", Posted = 23/02/2009 }
Topic { Title = "Fed Chairman admits guilt for causing second Great Depression", Posted = 06/15/2010 }
Tag { Name = "Politics", Color = "LightBlue" }
Topic { Title = "Political Debate #1", Posted = 01/02/2008 }
Topic { Title = "Fed Chairman admits guilt for causing second Great Depression", Posted = 06/15/2010 }
Tag { Name = ".NET", Color = "LightGreen" }
Topic { Title = "iPhone to support SiliverLight!", Posted = 23/02/2009 }
您可以假设任何重复的数据都是参考唯一的,即在内存中只有一个实例,并且这些只是对同一对象的几个引用。此外,合理的答案可以使用匿名类来生成投影,因为我意识到反转后类的形状可能会略有不同。
更新:我添加了下面的代码,设置了示例数据。我正在使用LinqPad尝试发布的答案和自己的一些想法。
var tags = new[]
{
new { Name = "Contraversial", Color = "Red" },
new { Name = "Politics", Color = "LightBlue" },
new { Name = ".NET", Color = "LightGreen" },
new { Name = "BleedingEdge", Color = "LightBlue" }
};
var topics = new[]
{
new
{
Title = "Political Debate #1",
Posted = DateTime.Parse("01/02/2008"),
Tags = (from t in tags where new []{"Contraversial", "Politics"}.Contains(t.Name) select t),
},
new
{
Title = "iPhone to support SiliverLight!",
Posted = DateTime.Parse("02/23/2009"),
Tags = (from t in tags where new []{"BleedingEdge", "Contraversial", ".NET", }.Contains(t.Name) select t),
},
new
{
Title = "Fed Chairman admits guilt for causing second Great Depression",
Posted = DateTime.Parse("06/15/2010"),
Tags = (from t in tags where new []{"Contraversial", "Politics"}.Contains(t.Name) select t),
},
};