这是我在博客园的第一篇文章,也是我第一次在想在博客中记录我的学习经历和心得,也说不上心得吧,因为知道自己还很菜。当然我回努力地,我相信只要努力学习和实践,我终有一天会跻身牛人的行列的,先把话撂在这里,把话说大了才有压力(我深知自己自制力不行,呵呵)。废话少说 现在开始吧。
    学习.net有些时间了,老早就听说.net有一个叫做“Linq”的技术很给力,后来用倒是用过不够只是停留在用用的级别,没有深入学习过。不过最近老师讲了一天MVC的课程,用到了.net Entity Framework ,我还是第一次接触这种ORM框架(高手们不要笑,本人确实是个菜鸟),感觉很神奇,决定静下心来好好琢磨琢磨。我选择从linq开始,不知道对不对,不过也管不了那么多了,先学了再说。
    首先我要解决的问题是 查询是什么?这个问题看似很简单不过我现在还真是说不清楚。我想笼统的说查询就是从某个地方(数据库、xml文件、磁盘文件、甚至也可能是互联网 程序员称它为数据源)查找,搜索我们想要的东西,也就是数据。那么对于不同的数据源我们用的查询方式也是不一样的,比如用于关系数据库的SQl和用户XML的XQurey(这个东东还是第一次听说记下来以后学习学习)。MSDN说“Linq simplifies this situation by offering a consistent model for working with data across various kinds of data sources and formats” 意思好像是说 Linq的出现解决了个问题。具体怎么解决的不知道,待以后研究吧。
   现在先来看看Link的的第一个例子(我是根据msdn的示例来做的)。
    首先在.net3.5下创建一个控制台项目LinqStart. 然后我们需要一个数据源,这里用一个从msdn 上面抄下来的Student类的List集合作为数据源。
/// <summary>
/// 从Msdn复制的示例实体类 Student
/// </summary>
public class Student
{
public string First { get; set; }
public string Last { get; set; }
public int ID { get; set; }
public List<int> Scores;
}
 在Program 类中添加一个静态字段,在以后的查询中都将以这个静态在字段作为数据源。
View Code
1 static List<Student> students = new List<Student>
2 {
3 new Student {First="Svetlana", Last="Jim", ID=111, Scores= new List<int> {97, 92, 81, 60}},
4 new Student {First="Claire", Last="Lily", ID=112, Scores= new List<int> {75, 84, 91, 39}},
5 new Student {First="Sven", Last="Jeek", ID=113, Scores= new List<int> {88, 94, 65, 91}},
6 new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {97, 89, 85, 82}},
7 new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {35, 72, 91, 70}},
8 new Student {First="Fadi", Last="Fakhouri", ID=116, Scores= new List<int> {99, 86, 90, 94}},
9 new Student {First="Hanying", Last="Feng", ID=117, Scores= new List<int> {93, 92, 80, 87}},
10 new Student {First="Hugo", Last="Garcia", ID=118, Scores= new List<int> {92, 90, 83, 78}},
11 new Student {First="Lance", Last="Tucker", ID=119, Scores= new List<int> {68, 79, 88, 92}},
12 new Student {First="Terry", Last="Adams", ID=120, Scores= new List<int> {99, 82, 81, 79}},
13 new Student {First="Eugene", Last="Zabokritski", ID=121, Scores= new List<int> {96, 85, 91, 60}},
14 new Student {First="Michael", Last="Tucker", ID=122, Scores= new List<int> {94, 92, 91, 91} }
15 };

那么下面让我们在控制台Main函数中创建一个Linq查询遍历Students静态字段中的所有Student并且在控制台输出每个学生的First和Last;
1 //创建一个查询
2 //这个查询的第一行还可以写成"var studentQuery="
3 IEnumerable<Student> queryResult =
4 from student in students
5 select student;
6 //由于queryResult是一个IEnumerable类型的变量,因此可以用foreach遍历
7 foreach(Student student in queryResult)
8 {
9 Console.WriteLine("{0},{1}", student.First, student.Last);
10 }


 F5执行,将在控制台输出所有Student的First和Last属性,这看起来没有什么稀奇的。 我们可以直接用foreach语句遍历students字段而且还少些了不少代码不用再去创建那个查询语句了呢。
  遍历linq查询结果(暂时这么说吧)和直接遍历Students集合可是有本质上不不同的。首先如果我们在Main函数中只写linq查询语句,而不用foreach循环遍历的话,linq语句是不会执行的。在这里queryResult只是保存了linq查询的表达式。只有当我们用foreach遍历数据源(students)的时候,程序会通过queryResult保存的表达式从数据源(students)中一个一个的取出数据然后交给我们在foreach语句进行处理。(下图来自Msdn)。
      为了验证这一点我修改了上面的代码,在foreach语句和linq查询语句之间又添加了几行代码,在查询语句之后,在遍历queryResult之前为students集合添加了一百个student对象。
1 //创建一个查询
2 //这个查询的第一行还可以写成"var studentQuery="
3 IEnumerable<Student> queryResult =
4 from student in students
5 select student;
6 //在执行遍历之前为数据源Students添加100个student对象
7 for (int i = 0; i < 100; i++)
8 {
9 students.Add(new Student()
10 {
11 First = "First" + i.ToString(),
12 Last = "Last" +i.ToString(),
13 Scores = new List<int>() { 90 + i, 90 + i, 90 + i, 90 + i },
14 ID = 1000 + i
15 });
16 }

18 //由于queryResult是一个IEnumerable类型的变量,因此可以用foreach遍历

19 foreach(Student student in queryResult)

20 {

21 Console.WriteLine("{0},{1}", student.First, student.Last);

22 }
       按照我们正常的理解,如果queryResult保存的是查询的结果,那么在执行查询语句之后再向数据源中添加数据应该是与queryResult无关的。应该只显示未执行for循环之前的数据。但是结果与我们想象的相反,控制台不仅输出了最先在Students字段中保存的数据,在linq语句之后循环添加的数据也被查询出来并输出了。这个结果也证明了在linq查询语句之前声明的变量其实并不是用来保存linq查询执行后的结果的。也就是说queryResult其实只是是个声明性的东东,如果说他保存了什么,那么他保存的因该是linq查询表达式。
  因此一个完整的Linq查询可以分为三个步骤:
    1、获得数据源,
    2、创建查询、
    3、执行查询
   换句话说、如果我们只是创建查询变量而不执行查询(遍历等操作),查询变量是不会从数据源中检索任何数据的。
 
     如果linq只是用来遍历数据集合那么,从上面的这个例子中也看不到什么优势,但是当我们需要对students集合更复杂的操作时就能体会树linq给我们带来的便利了。比如,如果我们希望知道平均成绩在330—370之间的学生的姓名,实现这样一个需求如果不用linq就需要写if语句了,但是使用linq只需要加一个where子句就可以了。而且由于查询变量只是保存了查询表达式,那么无论在什么地方如果对students添加了新的数据也是可以被查询出来的。
IEnumerable<String> queryResult =
from student
in students
where student.Scores.Sum() > 330 && student.Scores.Sum() < 370 //where 子句表示查询的筛选条件
select student.Last+""+student.First; //这里我们不再是得到Student对象而是返回他的名字
   使用这个linq查询语句不仅是代码看起来更加清晰、简洁,而且对查询结果进行处理时也更简单:
foreach(String name in queryResult)
{
Console.WriteLine(name);
}

 posted on 2011-05-24 22:31  小段段  阅读(698)  评论(0编辑  收藏  举报