这两天在家休息,就研究了下现在比较流行的Linq查询,以及lambda表达式和Func委托与Action委托,做了一些基础的测试,下面贴出代码,如有错误疏忽之处,请指出。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class LinqSelect : System.Web.UI.Page
{
public static int times = 0 ;
/*
*Linq查询,从一般的集合中检索一定的数据,一般可分为查询执行和立即执行,下面分别做一些解释:
*查询执行:按照相关说法,Linq查询在定义的时候并不会检索集合中的数据,即定义一个Linq查询而不去遍历这个结果集的话,Linq查询的检索操作将不会被执行;
*立即执行:即定义了Linq查询后就执行,这种定义需要将Linq查询转换为ToArray()或者ToList();
*
*官方说法:在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。
*官方地址: http://msdn.microsoft.com/zh-cn/library/bb397906.aspx 官方网址对上面二者进行了较好的描述
*/
protected void Page_Load( object sender, EventArgs e)
{
// 定义数据源
var numlist = new int [] { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
// 第一种定义方式:查询执行,定义了query对象后,实质上没有做任何的检索操作,待后面用到foreach后才执行这个query查询;
var query = from i in numlist
where i > 3 && i < 8
orderby i descending
select i;
// select query
foreach (var a in query)
{
Response.Write(a.ToString() + " <br /> " );
}
// 第二种定义方式:立刻执行,将Linq查询强制转换为某种类型,这样赋值给变量;
var query01 = (from i in numlist
where i % 2 == 0
orderby i ascending
select i).Reverse < int > ().ToArray(); // 经此,query01的类型为int[]
foreach (var a in query01)
{
Response.Write(a.ToString() + " <br /> " );
}
// 第三:连接两个Linq查询的结果集,关键方法(Contact),排除数组中的元素4和5
var query02 = (from a in numlist
where a % 2 == 0 && a != 4
orderby a descending
select a).Concat(
from b in numlist
where b % 2 == 1 && b != 5
orderby b ascending
select b);
foreach (var c in query02)
{
Response.Write(c.ToString() + " <br /> " );
}
// 第四:使用group by 子句,执行Linq查询
IList < GoodsEntity > goodsList = new List < GoodsEntity > ();
for (var i = 1 ; i <= 20 ; i ++ )
{
goodsList.Add( new GoodsEntity(i.ToString(), " GoodsName " , (i < 10 ? " 001 " : " 002 " )));
}
var query03 = from goods in goodsList
where goods.ClsID.Length > 0
group goods by goods.ClsID into jh
select jh;
/* 根据多个字段/条件分组
var query04 = from goods in goodsList
group goods by new { goods.GdId, goods.ClsID } into jh
select jh;
*/
/* 查询条件保存至匿名类中,
* 以下查询将结果保存至一个匿名类中,并赋予属性:clsid,g,属性可以随便加,不过要注明每个属性的类型
var query05 = from goods in goodsList
group goods by goods.ClsID into g
select new
{
clsid = g.Key,
g
};
foreach (var x in query05)
{
Response.Write(x.clsid);
foreach (GoodsEntity gd in x.g)
{
Response.Write(gd.Name + "<br />");
}
}
*/
foreach (var gd in query03) // 遍历每个组信息
{
Response.Write( " <br />分类 " + gd.Key.ToString() + " 下的商品列表:<br /> " );
foreach (GoodsEntity good in gd) // 遍历当前组下的列表信息
{
Response.Write(good.GdId + " : " + good.Name + " <br /> " );
}
}
// 第五:关于使用Linq查询ArrayList数据源,需要指明变量的类型
var list = new ArrayList();
for (var i = 1 ; i < 20 ; i ++ )
{
list.Add( new GoodsEntity(i.ToString(), " sweet " , (i < 10 ? " 001 " : " 002 " )));
}
var queryforArrayList = from GoodsEntity goods in list // 在from后面加上goods的类型
where int .Parse(goods.GdId) >= 5 && int .Parse(goods.GdId) <= 10
select goods;
foreach (GoodsEntity good in queryforArrayList)
{
Response.Write( string .Format( " 编号:{0},名称:{1}<br /> " , good.GdId, good.Name));
}
// 第六:Linq查询的方法语法(扩展方法),直接用数据源.where/orderby ....
// 数据源
string [] arr = new [] { " C# " , " VB " , " Flex " , " JS " , " Ajax " };
// IOrderedEnumerable<string> ss = arr.Where(ele => ele.Length > 2).OrderByDescending(ele => ele.Length);
string [] result = arr.Where(ele => ele.Length > 2 ).OrderByDescending(ele => ele.Length).ToArray < string > (); // 终于知道lamda表达式的好处了
string [] jieguo = arr.Where < string > ( new Func < string , bool > (testss)).ToArray < string > (); // 这种写法与lamda写法效果相同,只是lamda更方便
Response.Write( " <br /> " );
foreach ( string s in jieguo)
{
Response.Write(s + " , " );
}
// Func与Action委托
Func < int , int > fdel = getSquare;
// Func<int, int> xx = new Func<int, int>(getSquare); // 此定义与以上定义方式一致
Response.Write( " <br />使用Func<>泛型委托要求必须有返回值,本次返回值为: " + fdel( 9 ).ToString() + " <br /> " );
Action act = new Action(HelloWorld); // 无参委托
act();
Action < string > strAct = new Action < string > (WriteMsg);
strAct( null );
strAct( " C#.Action " );
Response.Write( " <br />次数: " + times.ToString());
}
// 与lamda表达式对比,原理可能是差不多的
private bool testss( string s) { times ++ ; if (s.Length > 2 ) return true ; else return false ; }
#region Method For Delegate
private int getSquare( int x)
{
return x * x;
}
private void HelloWorld()
{
Response.Write( " <br />Hello,World!<br /> " );
}
private void WriteMsg( string msg)
{
if (msg != null )
Response.Write( " <br />本次执行的参数为: " + msg.ToString());
else
Response.Write( " 本次执行没有参数。 " );
}
#endregion
}
// 分类实体类
public class ClassEntity
{
private string clid;
private string name;
/// <summary>
/// 分类编号
/// </summary>
public string ClId { set ; get ; }
/// <summary>
/// 分了名称
/// </summary>
public string Name { set ; get ; }
}
// 商品类
public class GoodsEntity
{
private string gdid;
private string name;
private string clsid;
/// <summary>
/// 商品编号
/// </summary>
public string GdId { set ; get ; }
/// <summary>
/// 商品名称
/// </summary>
public string Name { set ; get ; }
/// <summary>
/// 商品分类编号
/// </summary>
public string ClsID { set ; get ; }
public GoodsEntity() { }
public GoodsEntity( string id, string name, string clsid)
{
this .GdId = id;
this .Name = name;
this .ClsID = clsid;
}
}
关于Func委托与Action委托,推荐学习地址:http://www.cnblogs.com/wjfluisfigo/archive/2010/04/08/1512556.html
下载测试:代码
纠正一下:原来代码里面把lambda表达式写成了lamda表达式,呵呵,感谢 Arthas-Cui 的指出,也提醒下大家,跟着感觉走的时候偶尔还是要验证一下。