【问题标题】:Applying orderby to C# LINQ Inner join将 orderby 应用于 C# LINQ 内连接
【发布时间】:2014-07-18 21:02:28
【问题描述】:

我正在尝试来自 this msdn page 的 C# LINQ 联接。

我无法在内部加入上应用 order by,即使它适用于组加入。

运行查询的数据是:

    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},
    };

所需的输出是(在括号中按类别列出顺序,然后按产品列出):

Cola(Beverages)
Tea(Beverages)
Mustard(Condiments)
Pickles(Condiments)
Melons(Fruit)
Peaches(Fruit)
Bok Choy(Vegetables)
Carrots(Vegetables)

我能够使用group-joinorderby 和第二个from-select 生成此输出,以变形组层次结构并生成如下简单列表:

var listGroupJoinOrderBy =
            from category in categories
            join product in products on category.ID equals product.CategoryID into prodGroup
            from prod in prodGroup
            orderby category.Name, prod.Name  //first order by category name then product name
            select
            new
            {
                Category = category.Name,
                Product = prod.Name
            };

但是我无法将orderby 应用于内部连接(即没有into 子句的组连接)产生相同的输出。我尝试了以下变体:

变体 #1

var innerJoinOrderBy =
            from category in categories
            orderby category.Name    //orderby category name
            join product in products on category.ID equals product.CategoryID                
            orderby product.Name     //orderby product name
            select
            new
            {
                Category = category.Name,
                Product = product.Name
            };

变体 #2

var innerJoinOrderBy =
            from category in categories

            join product in products on category.ID equals product.CategoryID                
            orderby category.Name, product.Name     //orderby category first and then by product name
            select
            new
            {
                Category = category.Name,
                Product = product.Name
            };    

但是,这两种变体都提供相同的输出,就好像没有使用 orderby 一样,并产生以下输出:

Cola (Beverages)
Tea (Beverages)
Mustard (Condiments)
Pickles (Condiments)
Carrots (Vegetables)
Bok Choy (Vegetables)
Peaches (Fruit)
Melons (Fruit)

问。如何使用inner-joinorderby 生成所需的输出?

无论如何,要打印查询结果,可以使用以下foreach(只需更改查询变量名称):

foreach (var product in simpleInnerJoin)
{
    Console.WriteLine(product.Product + " (" + product.Category + ")");
}

【问题讨论】:

    标签: c# linq join inner-join


    【解决方案1】:

    您的第二个选项应该可以正常工作

    var innerJoinOrderBy =
                from c in categories
                join p in products on c.ID equals p.CategoryID
                orderby c.Name, p.Name
                select new {
                    Category = c.Name,
                    Product = p.Name
                };
    

    输出:

    [
        { Product="Cola", Category="Beverages" },
        { Product="Tea", Category="Beverages" },
        { Product="Mustard", Category="Condiments" },
        { Product="Pickles", Category="Condiments" },
        { Product="Melons", Category="Fruit" },
        { Product="Peaches", Category="Fruit" },
        { Product="Bok Choy", Category="Vegetables" },
        { Product="Carrots", Category="Vegetables" }
    ]
    

    从您的输出中,我看到项目按原始顺序排列。确保您在查询中应用了orderby 运算符。

    【讨论】:

    • 你的意思是在变体 2 中交换 productcategory
    • @Mahesha999 它的工作(我复制粘贴控制台输出)。你的第二种方法也有效。确保您应用了正确的orderby 运算符
    【解决方案2】:

    从主 Linq 中取出 Orderby 并使用

    foreach (var product in simpleInnerJoin.Orderby(i=> i.Category.Name).ThenBy(i=>i.Product.Name))
    {
        Console.WriteLine(product.Product + " (" + product.Category + ")");
    }
    

    我认为这应该可以为您提供所需的输出。

    【讨论】:

    • 对我来说有点沉重的人,那些扩展方法和 lambdas :'( 不能仅通过 LINQ 查询来完成吗?我很欣赏这一点,请不要删除您的答案。
    • 其他选项可能是添加第二个 Linq 我将添加到我的答案中
    • @DavidMolyneux 不需要使用额外的 Method 语法进行排序 - 您可以直接在查询中应用排序。也无需为订购编写额外的查询
    • @SergeyBerezovskiy 从答案中删除了它。我个人更喜欢将顺序与主连接分开,因为您可以在代码中的其他位置使用具有不同顺序的相同连接查询。
    • @DavidMolyneux 我会使用单个查询,除非您真的需要在多个地方进行不同的排序。 YAGNI :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多