我知道由于使用了单词,这个问题很奇怪。但这是this MSDN page上用来学习LINQ组连接的术语,我将解释它们。
我正在尝试LINQ的数据是:
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},
};
现在的条款:
简单/未命名的群组加入是我们直接选择群组的协议:
//...
join product in products on category.ID equals product.CategoryID into prodGroup
select prodGroup;
而不是选择匿名类型或使用嵌套的from-select
子句。
外键源是跟随from
关键字的数据源,内部密钥源是跟随join
的数据源关键字
我称简单的群组加入未命名(为了方便起见),因为我们在所选群组中没有外部密钥源名称/ ID。
我试图编写简单/未命名的查询,它将生成以下结果,首先是orderby外键源属性,然后是内部keyource属性:
Unnamed Group
Cola
Tea
Unnamed Group
Mustard
Pickles
Unnamed Group
Melons
Peaches
Unnamed Group
Unnamed Group
Bok Choy
Carrots
我可以通过外键源订购如下:
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);
}
}
但它正在产生以下输出:
Unnamed group
Cola
Tea
Unnamed group
Mustard
Pickles
Unnamed group
Peaches
Melons
Unnamed group
Unnamed group
Carrots
Bok Choy
但我无法在未命名的类别组下订购产品。
我知道我可以通过选择匿名类型来完成此操作:
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);
}
}
但是我只是想知道如果不选择匿名类型我是否可以这样做。 我觉得它在语法上与“两个”键源的顺序和选择匿名类型无关。 因此在查询本身应该有一些方法可以做到这一点如下,但它不起作用:
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;
答案 0 :(得分:2)
您可以在加入之前订购products
:
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
保留了外部元素的顺序,并且对于每个元素,内部匹配元素的顺序(引自MSDN)。
一些替代方案(更像您的例子):
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);
答案 1 :(得分:0)
我可能是错的。但我不认为你可以在没有完整select
的情况下做到这一点。我有点不同意匿名类型和order by
的选择是不相关的。
你select
查询中已经提到的那个东西,在这种情况下你不需要一个匿名类型,或者你根据它选择其他东西。如果你select
有其他内容,而不是查询前一部分给出的内容,则必须完整select
。
IINM这在SQL中是相同的 - 你需要一个子查询来做类似的事情(不是你要像这样选择整个组,但是如果你想做ORDER BY
后跟{ {1}})。
答案 2 :(得分:0)
我查看了您提供的链接中列出的代码,这是您问题的解决方案。您在查询中的原始订单只会订购类别,不会查看产品。如果您需要在问题中描述的订单,则还需要另一个子查询来订购产品:
var simpleGroupJoinOrderby =
from category in DBContext.categories
orderby category.Name //orderby outer ks
join product in DBContext.products on category.ID equals product.CategoryID into prodGroup
select prodGroup;
foreach (var unnamedGroup in simpleGroupJoinOrderby)
{
lblList.Text += "//Unnamed group";
var unnamedProductsGroup = unnamedGroup.OrderBy(z => z.Name).Select(group => new { name = group.Name, ID = group.CategoryID });
foreach (var product in unnamedProductsGroup)
{
//Console.WriteLine(" " + product.Name);
lblList.Text += "|" + product.name;
}
}