您的位置:首页 > 编程语言 > C#

C#:LINQ

2013-11-03 21:58 190 查看
刚刚接触LINQ,对这个语言集成查询(Language INtegrated Query)还很懵懂,遂记录下学习心得,方便以后查阅。

LINQ的写法形式有点像SQL,但它跟SQL是没有任何关系,它的作用主要就是用来处理对象的集合。

下面以一个简单的例子来展示LINQ的强大之处:

如:我要在一批电影集合中找出票价最便宜的前3部电影,下面的代码是以前的做法形式:

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

//用来保存查询结果
Movie[] ms = new Movie[3];

//按照价格属性重新排序
Array.Sort(movies, (item1, item2) => {
return Comparer<decimal>.Default.Compare(item1.price, item2.price);
});

//前3项拿出来
Array.Copy(movies, ms, 3);

foreach (var item in ms)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
}
Console.ReadLine();
}
}
public class Movie
{
public string Name { get; set; }
public string artist { get; set; }
public decimal price { get; set; }
}



现在,我直接用LINQ对此进行处理,看看结果如何:

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

var results = from ms in movies
orderby ms.price ascending
select new { ms.artist, ms.Name, ms.price };
int i = 0;
foreach (var item in results)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
if (i++==2)
{
break;
}
}

Console.ReadLine();
}




可以看到效果是一样的。相比老方式而言,使用LINQ清晰,容易看懂业务,也可以少敲很多繁杂代码。

但是,上面的LINQ也有缺点,就是引入了一个计数变量i,如果不引入,那么foreach会将所有元素打印出来。如果这样的计数变量多了,像什么i,j等乱七八糟的都有了之后,让人看了很是不舒服。怎么办呢?LINQ还有一种写法:

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

var results = movies
.OrderBy(m=>m.price)
.Take(3)
.Select(a=>new{a.artist,a.Name,a.price});

foreach (var item in results)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
}
Console.ReadLine();
}
这样,对于结果,就不用再引入计数器了。


还有一个值得一提的就是:LINQ的查询是延迟的,什么意思呢?就拿上面的例子来说,不执行foreach代码,那么上面LINQ的那段查询就不会执行。直到执行了foreach(即IEnumerable<T>结果中的条目被枚举时)才会执行查询。

可以测试一下:

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

var results = movies
.OrderBy(m=>m.price)
.Take(3)
.Select(a=>new{a.artist,a.Name,a.price});

//加了这一句
movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

foreach (var item in results)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
}
Console.ReadLine();
}
查询结果是:



可见,上面的LINQ查询是在新加的语句执行之后才执行的。

那如果我不想让LINQ查询在新加的语句执行之后才执行,我想让它立刻执行,怎么弄呢?

很简单,在新加的语句之前,执行一次foreach,如下:

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

var results = movies
.OrderBy(m=>m.price)
.Take(3)
.Select(a=>new{a.artist,a.Name,a.price});

foreach (var item in results)
{
Console.WriteLine(item.artist + "----" + item.Name + "----" + item.price);
}
//加了这一句
movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

foreach (var item in results)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
}
Console.ReadLine();
}


可以看到结果:LINQ查询了两遍!!!



其实除了foreach,还是有其它方式可以让LINQ立刻执行,比如:使用非延迟的扩展方法(如下面的Sum方法)。

static void Main(string[] args)
{
//构造一个对象集合
Movie[] movies =
{
new Movie{Name="晚秋",artist="汤唯",price=25.5M},
new Movie{Name="少林足球",artist="周星驰",price=35.7M},
new Movie{Name="叶问",artist="甄子丹",price=15.5M},
new Movie{Name="无间道",artist="刘德华",price=45.5M},
new Movie{Name="霸王别姬",artist="张国荣",price=50M},
new Movie{Name="邻家特工",artist="成龙",price=25.5M}
};

var results = movies
.OrderBy(m=>m.price)
.Take(3)
.Select(a=>new{a.artist,a.Name,a.price});

//LINQ执行查询
var sum = movies.Sum(e => e.price);
Console.WriteLine("Sum:"+sum);

//加了这一句
movies[2] = new Movie { Name = "叶问", artist = "甄子丹", price = 10M };

//LINQ执行查询
foreach (var item in results)
{
Console.WriteLine(item.artist+"----"+item.Name+"----"+item.price);
}

//LINQ执行查询
var sum1 = movies.Sum(e => e.price);
Console.WriteLine("Sum:" + sum1);

Console.ReadLine();
}
结果如下,可以看到LINQ执行了3次查询!!!



关于LINQ暂时就先记录到这啦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: