通过使用 LINQ 查询,可以将源序列用作输入,并采用多种方式修改它以创建新输出序列。可以通过排序和分组来修改序列本身,而不必修改元素本身。但是,LINQ 查询最强大的功能可能在于它能够创建新类型,这一功能在 select 子句中实现。
(一)Student
public
class
Student
{
public string FirstName { get ; set ; }
public string LastName { get ; set ; }
public int Unid { get ; set ; }
public List < int > Scores { get ; set ; }
}
{
public string FirstName { get ; set ; }
public string LastName { get ; set ; }
public int Unid { get ; set ; }
public List < int > Scores { get ; set ; }
}
(二)选择源元素子集
学生列表集合
List
<
Student
>
_list
=
new
List
<
Student
>
()
{
new Student {FirstName = " Svetlana " , LastName = " Omelchenko " ,
Unid = 111 , Scores = new List < int > { 97 , 92 , 81 , 60 }},
new Student {FirstName = " Claire " , LastName = " O’Donnell " ,
Unid = 112 , Scores = new List < int > { 75 , 84 , 91 , 39 }},
new Student {FirstName = " Sven " , LastName = " Mortensen " ,
Unid = 113 , Scores = new List < int > { 88 , 94 , 65 , 91 }}
};
{
new Student {FirstName = " Svetlana " , LastName = " Omelchenko " ,
Unid = 111 , Scores = new List < int > { 97 , 92 , 81 , 60 }},
new Student {FirstName = " Claire " , LastName = " O’Donnell " ,
Unid = 112 , Scores = new List < int > { 75 , 84 , 91 , 39 }},
new Student {FirstName = " Sven " , LastName = " Mortensen " ,
Unid = 113 , Scores = new List < int > { 88 , 94 , 65 , 91 }}
};
(1)选择一个成员
·选择FirstName
var list
=
from p
in
_list select p.FirstName;
foreach ( string s in list)
Console.WriteLine(s);
foreach ( string s in list)
Console.WriteLine(s);
这里可以使用匿名类型。因为select部分为字符串类型,所以,也可以是字符串型泛型集合
List
<
string
>
list
=
(from p
in
_list
select p.FirstName).ToList < string > ();
foreach ( string s in list)
Console.WriteLine(s);
select p.FirstName).ToList < string > ();
foreach ( string s in list)
Console.WriteLine(s);
·选择Scores
这里为整型泛型集合,
可以使用匿名类型
var list1
=
from p
in
_list select p.Scores;
foreach (var l in list1)
{
foreach ( int i in l)
Console.WriteLine(i);
}
foreach (var l in list1)
{
foreach ( int i in l)
Console.WriteLine(i);
}
因为结果集为整型泛型集合,所以也可以使用
List
<
List
<
int
>>
list
=
(from p
in
_list
select p.Scores).ToList < List < int >> ();
foreach (List < int > l in list)
{
foreach ( int i in l)
Console.WriteLine(i);
}
select p.Scores).ToList < List < int >> ();
foreach (List < int > l in list)
{
foreach ( int i in l)
Console.WriteLine(i);
}
(2)选择多个成员
·使用匿名类型
var q
=
from p
in
_list
select new { Name = p.FirstName + " · " + p.LastName };
foreach (var x in q)
Console.WriteLine(x.Name);
select new { Name = p.FirstName + " · " + p.LastName };
foreach (var x in q)
Console.WriteLine(x.Name);
其中select返回部分也为一个复合类型,所以在访问时,要以元素的.Name来访问。
如果使用匿名类型时,不采用别名赋值的话,会有异常:
无效的匿名类型成员声明符。匿名类型成员必须使用赋值、简单名称或成员访问来声明。
·使用命名对象
新建Sample类
public
class
Sample
{
public string Name { get ; set ; }
}
{
public string Name { get ; set ; }
}
使用
var q
=
from p
in
_list
select new Sample { Name = p.FirstName + " · " + p.LastName };
foreach (var x in q)
Console.WriteLine(x.Name);
select new Sample { Name = p.FirstName + " · " + p.LastName };
foreach (var x in q)
Console.WriteLine(x.Name);
发现与匿名类型复合值时相近。其实也就是:
List
<
Sample
>
list
=
(from p
in
_list
select new Sample { Name = p.FirstName + " · " + p.LastName }).ToList < Sample > ();
foreach (Sample x in list)
Console.WriteLine(x.Name);
select new Sample { Name = p.FirstName + " · " + p.LastName }).ToList < Sample > ();
foreach (Sample x in list)
Console.WriteLine(x.Name);
(三)转换为Xml
还是用上边那那个学生集合
List
<
Student
>
_list
=
new
List
<
Student
>
()
{
new Student {FirstName = " Svetlana " , LastName = " Omelchenko " ,
Unid = 111 , Scores = new List < int > { 97 , 92 , 81 , 60 }},
new Student {FirstName = " Claire " , LastName = " O’Donnell " ,
Unid = 112 , Scores = new List < int > { 75 , 84 , 91 , 39 }},
new Student {FirstName = " Sven " , LastName = " Mortensen " ,
Unid = 113 , Scores = new List < int > { 88 , 94 , 65 , 91 }}
};
var xele = new XElement( " Students " ,
from student in _list
let x = String.Format( " {0},{1},{2},{3} " ,
student.Scores[ 0 ],
student.Scores[ 1 ],
student.Scores[ 2 ],
student.Scores[ 3 ])
select new XElement( " student " ,
new XElement( " FirstName " ,student.FirstName),
new XElement( " LastName " , student.LastName),
new XElement( " Unid " , student.Unid),
new XElement( " Scores " , x)
)
);
Console.WriteLine(xele);
{
new Student {FirstName = " Svetlana " , LastName = " Omelchenko " ,
Unid = 111 , Scores = new List < int > { 97 , 92 , 81 , 60 }},
new Student {FirstName = " Claire " , LastName = " O’Donnell " ,
Unid = 112 , Scores = new List < int > { 75 , 84 , 91 , 39 }},
new Student {FirstName = " Sven " , LastName = " Mortensen " ,
Unid = 113 , Scores = new List < int > { 88 , 94 , 65 , 91 }}
};
var xele = new XElement( " Students " ,
from student in _list
let x = String.Format( " {0},{1},{2},{3} " ,
student.Scores[ 0 ],
student.Scores[ 1 ],
student.Scores[ 2 ],
student.Scores[ 3 ])
select new XElement( " student " ,
new XElement( " FirstName " ,student.FirstName),
new XElement( " LastName " , student.LastName),
new XElement( " Unid " , student.Unid),
new XElement( " Scores " , x)
)
);
Console.WriteLine(xele);
现在分析一下:
(1)Xelement元素的构造方法
public
XElement(XName name,Object[] content)
(2)上边的生成xml的构造方法其实使用的就是这个
第一部分:"Students"为根元素
而下边那么多其实是一行的内容,即占用第二个参数,要记住一句话 查询在select中实现。所以意思就是返回Xelement类型的结果集,而这个结果集正好为构造方法中Object[] content部分。
可知道student这个元素包含4个子节点。而Scores这里是List<int>类型,所以设定了返回类型及格式为字符串且用逗号隔开。(Let:可以将表达式结果存放在新的范围变量中)。