如何:对数据分组(实体框架)
本主题介绍如何对查询结果分组。 此示例返回一组嵌套的数据记录,其中包含 Contact.LastName 列,此列已按 Contact.LastName 的第一个字母以字符顺序分组和排序。 将使用以下每种实体框架 查询技术演示同一示例:
LINQ to Entities
Entity SQL 以及 ObjectQuery<T>
ObjectQuery<T> 的查询生成器方法
本主题中的示例基于 Adventure Works 销售模型。若要运行本主题中的代码,则必须已经将 Adventure Works 销售模型添加到了您的项目中,并且已经将项目配置为使用实体框架。有关更多信息,请参见如何:使用实体数据模型向导(实体框架)或如何:手动配置实体框架项目和如何:手动定义实体数据模型(实体框架)。
示例
以下是 LINQ to Entities 示例。
Using context As New AdventureWorksEntities
Dim contacts As ObjectSet(Of Contact) = context.Contacts
Dim query = ( _
From contact In contacts _
Group By firstLetter = contact.LastName.Substring(0, 1) _
Into contactGroup = Group _
Select New With {.FirstLetter = firstLetter, .Names = contactGroup}) _
.OrderBy(Function(letter) letter.FirstLetter)
For Each n In query
Console.WriteLine("Last names that start with the letter '{0}':", _
n.FirstLetter)
For Each name In n.Names
Console.WriteLine(name.LastName)
Next
Next
End Using
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
var query = (
from contact in context.Contacts
group contact by contact.LastName.Substring(0, 1) into contactGroup
select new { FirstLetter = contactGroup.Key, Names = contactGroup }).
OrderBy(letter => letter.FirstLetter);
foreach (var contact in query)
{
Console.WriteLine("Last names that start with the letter '{0}':",
contact.FirstLetter);
foreach (var name in contact.Names)
{
Console.WriteLine(name.LastName);
}
}
}
以下是 Entity SQL 示例。
Using context As New AdventureWorksEntities()
Dim esqlQuery As String = "SELECT ln, (SELECT c1.LastName FROM AdventureWorksEntities.Contacts " & _
" AS c1 WHERE SUBSTRING(c1.LastName ,1,1) = ln) AS CONTACT FROM AdventureWorksEntities.Contacts AS c2 " & _
" GROUP BY SUBSTRING(c2.LastName ,1,1) AS ln ORDER BY ln"
For Each rec As DbDataRecord In New ObjectQuery(Of DbDataRecord)(esqlQuery, context)
Console.WriteLine("Last names that start with the letter '{0}':", rec(0))
Dim list As List(Of DbDataRecord) = TryCast(rec(1), List(Of DbDataRecord))
For Each nestedRec As DbDataRecord In list
For i As Integer = 0 To nestedRec.FieldCount - 1
Console.WriteLine(" {0} ", nestedRec(i))
Next
Next
Next
End Using
using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
string esqlQuery = @"SELECT ln,
(SELECT c1.LastName FROM AdventureWorksEntities.Contacts
AS c1 WHERE SUBSTRING(c1.LastName ,1,1) = ln)
AS CONTACT
FROM AdventureWorksEntities.Contacts AS c2 GROUP BY SUBSTRING(c2.LastName ,1,1) AS ln
ORDER BY ln";
foreach (DbDataRecord rec in
new ObjectQuery<DbDataRecord>(esqlQuery, context))
{
Console.WriteLine("Last names that start with the letter '{0}':",
rec[0]);
List<DbDataRecord> list = rec[1] as List<DbDataRecord>;
foreach (DbDataRecord nestedRec in list)
{
for (int i = 0; i < nestedRec.FieldCount; i++)
{
Console.WriteLine(" {0} ", nestedRec[i]);
}
}
}
}
以下是查询生成器方法示例。
Using context As New AdventureWorksEntities()
' Define the query with a GROUP BY clause that returns
' a set of nested LastName records grouped by first letter.
Dim query As ObjectQuery(Of DbDataRecord) = _
context.Contacts.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln") _
.Select("it.ln AS ln, (SELECT c1.LastName FROM AdventureWorksEntities.Contacts AS c1 " & _
"WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT").OrderBy("it.ln")
' Execute the query and walk through the nested records.
For Each rec As DbDataRecord In query.Execute(MergeOption.AppendOnly)
Console.WriteLine("Last names that start with the letter '{0}':", rec(0))
Dim list As List(Of DbDataRecord) = TryCast(rec(1), List(Of DbDataRecord))
For Each r As DbDataRecord In list
For i As Integer = 0 To r.FieldCount - 1
Console.WriteLine(" {0} ", r(i))
Next
Next
Next
End Using
using (AdventureWorksEntities context =
new AdventureWorksEntities())
{
// Define the query with a GROUP BY clause that returns
// a set of nested LastName records grouped by first letter.
ObjectQuery<DbDataRecord> query =
context.Contacts
.GroupBy("SUBSTRING(it.LastName, 1, 1) AS ln", "ln")
.Select("it.ln AS ln, (SELECT c1.LastName " +
"FROM AdventureWorksEntities.Contacts AS c1 " +
"WHERE SubString(c1.LastName, 1, 1) = it.ln) AS CONTACT")
.OrderBy("it.ln");
// Execute the query and walk through the nested records.
foreach (DbDataRecord rec in
query.Execute(MergeOption.AppendOnly))
{
Console.WriteLine("Last names that start with the letter '{0}':",
rec[0]);
List<DbDataRecord> list = rec[1] as List<DbDataRecord>;
foreach (DbDataRecord r in list)
{
for (int i = 0; i < r.FieldCount; i++)
{
Console.WriteLine(" {0} ", r[i]);
}
}
}
}