如何将LINQ组和订购与父表和子表结合起来?

时间:2013-12-11 20:29:32

标签: c# linq group-by

我正在尝试将特定的LINQ结果集排序并分组。

我有两个模型,GalleryMedia。画廊包含媒体。

GalleryMedia个对象都是由名为SortOrder的键(列)排序。

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

  1. GalleryId(图库键)
  2. 分组
  3. Gallery.SortOrder
  4. 排序的画廊
  5. Media.SortOrder
  6. 订购的媒体

    所以结果集看起来像:

    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;
    

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

    EventGalleries数组已按正确顺序排列,我现在确定EventMedia是否会以这种方式正确排序/分组。

3 个答案:

答案 0 :(得分: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);

这是working demo

答案 1 :(得分: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
                }

            }

答案 2 :(得分: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;
    }
}

无论哪种方式,您都会获得GalleryMedia的列表:

Console.WriteLine(string.Join(Environment.NewLine, GetGalleriesAndMedia(1)));
// outputs
Gallery 1
Media 1
Media 2
Media 3
Gallery 2
Media 1
Media 2
Media 3
Gallery 3
Media 1
Media 2
Media 3