如何将LINQ分组和排序与父子表相结合?

3

我试图对特定的LINQ结果集进行排序和分组。

我有两个模型,一个是Gallery(相册),另一个是Media(媒体)。相册包含媒体。

GalleryMedia对象都按照一个名为SortOrder的关键字(列)排序。

我正在尝试制作一个选择器,返回一组相册中的所有媒体,但需要:

  1. GalleryId(相册关键字)分组
  2. Gallery.SortOrder排序相册
  3. Media.SortOrder排序媒体

因此,结果集应该如下所示:

Gallery 1
Media 1
Media 2
Media 3
Gallery 2
Media 1
Media 2
Media 3
Gallery 3
Media 1
Media 2
Media 3

我目前有:

var EventGalleries = from g in db.Galleries
                     where g.EventId == id
                     orderby g.SortOrder
                     select g.GalleryId;

var EventMedia = from m in db.Media
                 where EventGalleries.Contains(m.GalleryId)
                 orderby m.SortOrder ascending
                 select m;

现在我需要重新排序或按EventGalleries.SortOrder属性对EventMedia列表进行分组。

EventGalleries数组已经按正确顺序排列,但我不确定EventMedia是否会按此方式正确排序/分组。

3个回答

3
您可以尝试使用一个查询来完成此操作,使用JoinGroupBy函数:
var result = db.Media
    .OrderBy(m => m.SortOrder)
    .GroupBy(m => m.GalleryId)
    .Join(
        db.Galleries, 
        group => group.Key,
        g => g.GalleryId,
        (group, g) => new { Gallery = g, Media = group })
    .OrderBy(x => x.Gallery.SortOrder);

这里有一个可用的演示:(链接)

1
请注意,上述内容仅适用于您可以保证所有图库都至少有1个媒体的情况。如果存在一个没有媒体的图库g3,则g3将不会出现在输出中。请参见工作演示的分支。http://ideone.com/RWgaxt - Robert Paulson

1
尝试这个,它会给你想要的东西:

var items = (from g in db.Galleries
                  group g by g.GalleryId into k
                     orderby g.SortOrder
                         select new
                         {
                             Gallery = k.Key,
                             Medias = (from m in db.Media
                                       where m.GalleryId == k.Key
                                       orderby m.SortOrder
                                       select m).ToList()
                         });

            foreach (var g in items)
            {
                Console.Writeline(g.Gallery);
                foreach (var m in g.Medias)
                {
                    // write your media properties here
                }

            }

1
假设Gallery有一个列出其Media子项的Media属性,您可以编写一个简单的迭代器方法:
IEnumerable<object> GetGalleriesAndMedia(int eventId)
{
    foreach (var gallery in from g in db.Galleries
                            where g.EventId == eventId
                            orderby g.SortOrder
                            select g)
    {
        yield return gallery;
        foreach (var media in gallery.Media.OrderBy(m => m.SortOrder))
            yield return media;
    }
}

如果您没有这样的属性,您可以手动查找:
IEnumerable<object> GetGalleriesAndMedia(int eventId)
{
    var eventGalleries = (from g in db.Galleries
                         where g.EventId == eventId
                         orderby g.SortOrder
                         select g).ToList();
    var eventGalleryIds = eventGalleries.Select(x => x.GalleryId).ToList();
    var eventMedia = (from m in db.Media
                      where eventGalleryIds.Contains(m.GalleryId)                          
                      orderby m.SortOrder ascending 
                      select m).ToLookup(x => x.GalleryId);
    foreach (var gallery in eventGalleries)
    {
        yield return gallery;
        foreach (var media in eventMedia[gallery.GalleryId].OrderBy(m => m.SortOrder))
            yield return media;
    }
}

无论哪种方式,您都将获得您的图库媒体列表:
Console.WriteLine(string.Join(Environment.NewLine, GetGalleriesAndMedia(1)));
// outputs
图库 1
媒体 1
媒体 2
媒体 3
图库 2
媒体 1
媒体 2
媒体 3
图库 3
媒体 1
媒体 2
媒体 3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接