在简单/未命名的C#LINQ组联接中订购内部键源 [英] Ordering inner keysource in simple/unnamed C# LINQ group join
问题描述
我知道这个问题由于使用了单词而显得很奇怪.但这是此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屋!