在简单/未命名的C#LINQ组联接中订购内部键源 [英] Ordering inner keysource in simple/unnamed C# LINQ group join

查看:87
本文介绍了在简单/未命名的C#LINQ组联接中订购内部键源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题由于使用了单词而显得很奇怪.但这是此MSDN页面上使用的术语LINQ小组加入,我将向他们解释.

I know the question reads weird due to words used. But this is the terminology used on this MSDN page from where I am learning LINQ group joins and I am going to explain them.

我正在尝试使用LINQ的数据是:

The data on which I am trying LINQ is:

    class Product
    {
        public string Name { get; set; }
        public int CategoryID { get; set; }
    }

    class Category
    {
        public string Name { get; set; }
        public int ID { get; set; }
    }

    // Specify the first data source.
    static List<Category> categories = new List<Category>()
    { 
        new Category(){Name="Beverages", ID=001},
        new Category(){ Name="Condiments", ID=002},
        new Category(){ Name="Vegetables", ID=003},
        new Category() {  Name="Grains", ID=004},
        new Category() {  Name="Fruit", ID=005}            
    };

    // Specify the second data source.
    static List<Product> products = new List<Product>()
    {
        new Product{Name="Cola",  CategoryID=001},
        new Product{Name="Tea",  CategoryID=001},
        new Product{Name="Mustard", CategoryID=002},
        new Product{Name="Pickles", CategoryID=002},
        new Product{Name="Carrots", CategoryID=003},
        new Product{Name="Bok Choy", CategoryID=003},
        new Product{Name="Peaches", CategoryID=005},
        new Product{Name="Melons", CategoryID=005},
    };

现在这些条款:

  • 简单/未命名的组联接是我们直接选择组的一种:

  • Simple/unnamed group join is one in which we directly select group:

//... 
join product in products on category.ID equals product.CategoryID into prodGroup                      
        select prodGroup;

而不是选择匿名类型或使用嵌套的from-select子句.

instead of selecting anonymous type or using nested from-select clause.

外部密钥源是紧随from关键字的数据源,内部密钥源是紧随join关键字

Outer keysource in LINQ group join is a datasource that follows from keyword, inner keysource is a datasource that follows join keyword

我将简单的组联接称为未命名(为了方便起见),因为在选定的组中没有外部密钥源名称/Id.

I call simple group join unnamed (for convinience sake), since we dont have the outer keysource name/Id in selected group.

我试图编写简单/未命名的查询,该查询将产生以下结果,首先是按外部keysource属性排序,然后按内部keysource属性排序:

I was trying to write simple/unnamed query that will produce following result, first orderby outer keysource attribute and then by inner keysource attribute:

Unnamed Group
  Cola
  Tea
Unnamed Group
  Mustard
  Pickles
Unnamed Group
  Melons
  Peaches
Unnamed Group
Unnamed Group
  Bok Choy
  Carrots

我可以通过外部密钥源进行订购,如下所示:

I am able to order by outer keysource as follows:

var simpleGroupJoinOrderby = 
        from category in categories
        orderby category.Name           //orderby outer ks
        join product in products on category.ID equals product.CategoryID into prodGroup                      
        select prodGroup;

foreach (var unnamedGroup in simpleGroupJoinOrderby)
{   
    Console.WriteLine("Unnamed group");
    foreach(var product in unnamedGroup)
    {
        Console.WriteLine("  " + product.Name);
    }
}

但是它正在产生以下输出:

But it is producing following output:

Unnamed group
  Cola
  Tea
Unnamed group
  Mustard
  Pickles
Unnamed group
  Peaches
  Melons
Unnamed group
Unnamed group
  Carrots
  Bok Choy

但是我无法在未命名类别"组下订购产品.

But I am unable order products under unnamed categories group.

我知道我可以通过如下选择匿名类型来做到这一点:

I know I can do this by selecting anonymous type as follows:

        var namedGroupJoinOrderBy =
            from category in categories
            orderby category.Name  //order group hierarchy by name
            join product in products on category.ID equals product.CategoryID into prodGroup
            select
            new
            {
                Category = category.Name,
                Products = from prod in prodGroup
                           orderby prod.Name       //order by prodGroup.prod.Name under particular group hierarchy
                           select prod
            };

        foreach (var category in namedGroupJoinOrderBy)
        {
            Console.WriteLine("Category : " + category.Category);
            foreach (var product in category.Products)
            {
                Console.WriteLine("   " + product.Name);
            }
        }

但是,我只想知道是否可以在不选择匿名类型的情况下进行相同的操作. 我认为与两个"键源上的顺序和选择匿名类型在语法上都无关. 因此,在查询本身中应该有一些方法可以这样做,如下所示,但不起作用:

However I just want to know if I can do the same without selecting the anonymous type. I feel it should be syntactically un-related to order on "both" keysources and selecting the anonymous type. Thus there should be some way to do this in query itself as follows, but its not working:

var simpleGroupJoinOrderby = 
            from category in categories
            orderby category.Name           //orderby outer ks
            join product in products on category.ID equals product.CategoryID into prodGroup    
            orderby product.Name   //Err: The name 'product' does not exist in the current context
            select prodGroup;

推荐答案

您可以在加入之前订购products:

You could just order products before joining:

var simpleGroupJoinOrderby = 
    from category in categories
    orderby category.Name     
    join product in products.OrderBy(p => p.Name) 
        on category.ID equals product.CategoryID into prodGroup                      
    select prodGroup;

结果是:

Unnamed group
  Cola
  Tea
Unnamed group
  Mustard
  Pickles
Unnamed group
  Melons
  Peaches
Unnamed group
Unnamed group
  Bok Choy
  Carrots

之所以起作用,是因为Join保留了外部元素的顺序,对于每个这些元素,都保留了内部匹配元素的顺序(引自

It works because Join preserves the order of the elements of outer, and for each of these elements, the order of the matching elements of inner (quoted from MSDN).

一些替代方法(更像您的示例):

Some alternatives (more like your examples):

var simpleGroupJoinOrderby = categories.OrderBy (c => c.Name)
                                       .GroupJoin(products, 
                                                  c => c.ID, 
                                                  p => p.CategoryID, 
                                                  (c, ps) => ps.OrderBy(p => p.Name));

var simpleGroupJoinOrderby = from category in categories
                             orderby category.Name     
                             join product in products
                                on category.ID equals product.CategoryID into prodGroup                      
                             select prodGroup.OrderBy(g => g.Name); 

这篇关于在简单/未命名的C#LINQ组联接中订购内部键源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆