Как написать запрос LINQ, который берет иерархические исходные данные и преобразует их так, что группировка инвертируется?
Скажем, у меня есть список объектов Темы, каждый из которых содержит коллекцию тегов, представляющих теги метаданных по этой теме. Мне нужно написать запрос LINQ, чтобы по существу перевернуть иерархию наизнанку, чтобы у меня был список тегов, в каждом из которых есть набор тем, помеченных этим конкретным тегом.
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),
},
};