--------------------------------------------------------------------------------
Where,Select
--------------------------------------------------------------------------------
(1)Where:这个与SQL基本没什么不同,起一个过滤作用,能使用在group之前或之后.
(2)select:而select也基本一样,这里select是指定range variable详细信息,还有一个作用就是指定query variable(这个就在LINQ中的一般查寻的结构能看懂吧:var query variable = from string range variable in myName select range variable).
--------------------------------------------------------------------------------
Group
--------------------------------------------------------------------------------
Group返回的是一个IGrouping(TKey, TElement)的有序对象包括0个或更多个匹配分组的键值的项.
我们需要先知道IGrouping(TKey, TElement);
public interface IGrouping <TKey,TElement> : IEnumerable<TElement>,
IEnumerable
{
TKey Key { get; } // Key applies to the subsequence as a whole
}
参数:
TKey:是在IGrouping(TKey, TElement)中key的类型,
TElement:在IGrouping(TKey, TElement)中值的类型
IGrouping(TKey, TElement)是一个IEnumerable(T)多加一个Key,而这个key在这个里面是属性,也是这个里面每一个值都有的共同的这个属性,这个key我们可以指定实体中任何存在的值.当然也可以是任何类型.下面的事例来于MSDN中的,就反射String对象中的成员,我们再将这些成员按Key分组输出.(你可以把 First()方法换成Last方法来调试,你就知道Group关键是指定这个Key).
//use IGroup
IGrouping<MemberTypes, MemberInfo> group =
typeof(String).GetMembers().GroupBy(member => member.MemberType).First();
Console.WriteLine("\nValues that have the key'{0}':", group.Key);
foreach (MemberInfo mi in group)
Console.WriteLine(mi.Name);
Console.ReadKey();
因为IGrouping(TKey, TElement)对象由group产生,实质就是一个List,所以你必须使用foreach.而且在执行时是keySelector和ElementSelector同时存在。
这里运行时的IL
elementSelector =
{System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,
CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student>}
base {System.Delegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,
CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student>}
keySelector = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}
base {System.MulticastDelegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}
base {System.Delegate} = {System.Func<CSharpLanguage_C_app.LinqAPP.Linqkey.keyWord2.Student,char>}
回到我们的Group中来看代码,
数据源:
Code
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
}
public static List<Student> GetStudents()
{
// Use a collection initializer to create the data source. Note that each element
// in the list contains an inner sequence of scores.
List<Student> students = new List<Student>
{
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81, 60}},
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}},
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91, 95}},
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}},
new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}},
new Student {First="Eugene", Last="Zabokritski", ID=116, Scores= new List<int> {96, 85, 91, 60}},
new Student {First="Michael", Last="Tucker", ID=117, Scores= new List<int> {94, 92, 91, 91} }
};
return students;
}
一般的使用
List<Student> students = GetStudents();
var booleanGroupQuery = from student in students
group student by student.Scores.Average() >= 80;
foreach (var studentGroup in booleanGroupQuery)
{
Console.WriteLine(studentGroup.Key
== true ? "High averages" : "Low averages");
foreach (var student in studentGroup)
{
Console.WriteLine(" {0}, {1}:{2}",
student.Last, student.First, student.Scores.Average());
}
}
key可以是任何值
var studentQuery2 = from student in students
let avg = (int)student.Scores.Average()
group student by (avg == 0 ? 0 : avg / 100) into g
orderby g.Key
select g;
foreach (var studentGroup2 in studentQuery2)
{
int temp = studentGroup2.Key * 10;
Console.WriteLine("Students with an average between {0} and {1}",
temp, temp + 10);
foreach (var student in studentGroup2)
{
Console.WriteLine(" {0}, {1}:{2}",
student.Last, student.First, student.Scores.Average());
}
}
还可以使用匿名类创建混合的KEY.
// Composite Keys
var studentQuery6 = from f in students
group f by new { FirstName = f.First[0], idNumeber = f.Last[0] };
foreach (var s in studentQuery6)
{
Console.WriteLine(s.Key);
foreach (var news in s)
{
Console.WriteLine(news.First + "___" + news.ID + "___" + news.Last);
}
}
IGrouping<key,Element>得用法
//usage IGrouping<key,Element>
IEnumerable<IGrouping<char, Student>> studentQuery4 =
from student in students
group student by student.Last[0];
foreach (IGrouping<char, Student> group in studentQuery4)
{
Console.WriteLine(group.Key);
foreach (Student s in group)
{
Console.WriteLine(" {0}, {1}", s.Last, s.First);
}
}