【问题标题】:LINQ with Subquery/Group By/Join带有子查询/分组依据/加入的 LINQ
【发布时间】:2009-01-14 04:08:33
【问题描述】:

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......

表格:内容页面
Page_ID.......Section_ID.......标题........SortOrder
....11.............1........第 1 页.............1.... .
....12.............1........第二页.............3.... ..
....13............2............第三页............2......
....16........2........第四页............4......
....17............2............第 8 页............5......
....18........1........第 10 页............6.... ..

上面的查询可能会写成另一种方式,所以这就是我想要做的:

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

上面的 sql 查询没有涵盖最后 2 点,而更多的是“很高兴拥有”...

期望的结果
Page_ID.......Section_ID...SectionName.....Title.......SortOrder
....11......1............一个............第一个............ ...1......
....13........2............第二个............第三页...... ..2......

感谢任何帮助。谢谢!

【问题讨论】:

    标签: linq


    【解决方案1】:

    这是我的第一次尝试:

    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;
    

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

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

    【讨论】:

      【解决方案2】:

      我想这就是你要找的……

          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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多