LINQ with Subquery / Group By / Join

时间:2009-01-13 19:06:51

标签: linq

新手到LINQ,并尝试编写以下查询...

select 
  f.Section_ID, 
  f.Page_ID, 
  f.SortOrder, 
  f.Type
from 
(
  select 
    Section_ID, 
    min(SortOrder) as minSortOrder
  from 
    ContentPages 
  group by 
    Section_ID
) as x 
inner join 
  ContentPages as f on 
    f.Section_ID = x.Section_ID and 
    f.SortOrder = x.minSortOrder;

注意:

  • 'Section'有很多'ContentPages'
  • 章节按“SortOrder”字段排序
  • ContentPages也按'SortOrder'字段
  • 排序

表:部分
SECTION_ID ....名称....... SortOrder的
.... 1 .........一个.......... 1 ......
.... 2 .........两个.......... 3 ......
.... 3 .........三........ 2 ......

表:ContentPage
PAGE_ID ....... SECTION_ID .......标题.............. SortOrder的
.... 11 ............. 1 .......... Page One ............. 1 ..... 。
.... 12 ............. 1 ........... Page 2 ............. 3 .... ..
.... 13 ............. 2 ........... Page 3 ........... 2 ......
.... 16 ............. 2 ..........第四页............ 4 ......
.... 17 ............. 2 ...........第八页........... 5 ......
.... 18 ............. 1 ........... Page Ten ............. 6 .... ..

上面的查询可能是用另一种方式编写的,所以这就是我要做的事情:

  • 我需要返回每个Section中第一个ContentPage的列表(按ContentPage.SortOrder排序时)
  • 按Section.SortOrder
  • 排序结果
  • 在结果中显示Section.Name(在Section_ID上加入?)

上面的sql查询不包含最后2个点,更多的是“很高兴”......

期望的结果
PAGE_ID ....... SECTION_ID ... SectionName .....标题.............. SortOrder的
.... 11 ............. 1 ......... One ......... Page One .......... ...... 1 ......
.... 13 ............. 2 .........两个..........第三页......... ..2 ......

感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:8)

这是我第一次尝试:

from sectionPage in pages
group sectionPage by sectionPage.Section_ID into sectionGroup
join page in pages on sectionGroup.Key equals page.Section_ID
where page.SortOrder == sectionGroup.Min(p => p.SortOrder)
orderby page.SortOrder
select page;

首先我们在section id上创建一个组,以便我们稍后可以获得最小排序顺序。接下来,我们在section id上加入对页面的新引用,并且SortOrder的过滤是section节中的最小值。注意,对于像Min()调用这样的简单表达式,我更喜欢内联lambda表达式而不是另一个查询。

最后,我们添加一个orderby来订购页面,然后我们返回页面(请注意,如果您愿意,可以将其更改为某些字段。)

答案 1 :(得分:5)

我认为这就是你要找的......

    internal class Section
    {
        public int SectionId { get; set; }
        public string Name { get; set; }
        public int SortOrder { get; set; }
    }

    internal class ContentPage
    {
        public int PageId { get; set; }
        public int SectionId { get; set; }
        public string Title { get; set; }
        public int SortOrder { get; set; }
    }

    static void Main(string[] args)
    {
        List<Section> sections = new List<Section>();
        sections.Add(new Section() { SectionId = 1, Name = "One", SortOrder = 1 });
        sections.Add(new Section() { SectionId = 2, Name = "Two", SortOrder = 3 });
        sections.Add(new Section() { SectionId = 3, Name = "Three", SortOrder = 2 });

        List<ContentPage> contentPages = new List<ContentPage>();
        contentPages.Add(new ContentPage() { PageId = 11, SectionId = 1, Title = "Page One",   SortOrder = 1 });
        contentPages.Add(new ContentPage() { PageId = 12, SectionId = 1, Title = "Page Two",   SortOrder = 3 });
        contentPages.Add(new ContentPage() { PageId = 13, SectionId = 2, Title = "Page Three", SortOrder = 2 });
        contentPages.Add(new ContentPage() { PageId = 16, SectionId = 2, Title = "Page Four",  SortOrder = 4 });
        contentPages.Add(new ContentPage() { PageId = 17, SectionId = 2, Title = "Page Eight", SortOrder = 5 });
        contentPages.Add(new ContentPage() { PageId = 18, SectionId = 1, Title = "Page Ten",   SortOrder = 6 });

        var items = from section in sections
                     orderby section.SortOrder
                     join contentPage in
                         (from contentPage in contentPages
                          orderby contentPage.SortOrder
                          group contentPage by contentPage.SectionId into grp
                          select grp.FirstOrDefault())
                     on section.SectionId equals contentPage.SectionId
                     select new
                     {
                         PageId = contentPage.PageId,
                         SectionId = section.SectionId,
                         SectionName = section.Name,
                         Title = contentPage.Title,
                         SortOrder = section.SortOrder
                     };

        foreach (var newItem in items)
        {
            Console.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}", newItem.PageId, newItem.SectionId, newItem.SectionName, newItem.Title, newItem.SortOrder));
        }
    }

请注意,您提供的示例数据显示第2部分的排序顺序为3,但您的示例结果将其排序顺序列为2。