LINQ 基础知识 及 方法语法

LINQ( Language Integrated Query )即语言集成查询
LINQ 是一组语言特性和API,使得你可以使用统一的方式编写各种查询。查询的对象包括XML、对象集合、SQL Server 数据库等等。

LINQ 主要包含以下三部分:
LINQ to Objects 主要负责对象的查询
LINQ to XML 主要负责 XML 的查询
LINQ to ADO.NET 主要负责数据库的查询
              LINQ to SQL
              LINQ to DataSet
              LINQ to Entities

如图:

 

LINQ查询的两种方式
1、Method Syntax 方法语法:利用扩展方法和Lamda表达式方式查询

2、Query  Syntax 查询语法:标准的LINQ查询运算符(优先选择)


class QueryVMethodSyntax
{
    static void Main()
    {
        int[] numbers = { 5, 10, 8, 3, 6, 12};

        //查询语法:
        IEnumerable<int> numQuery1 = 
            from num in numbers
            where num % 2 == 0
            orderby num
            select num;

        //方法语法:
        IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n);

        foreach (int i in numQuery1)
        {
            Console.Write(i + " ");
        }
        Console.WriteLine(System.Environment.NewLine);
        foreach (int i in numQuery2)
        {
            Console.Write(i + " ");
        }

        // Keep the console open in debug mode.
        Console.WriteLine(System.Environment.NewLine);
        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}
/*
    Output:
    6 8 10 12
    6 8 10 12
 */


一、初步体验

            int[] arr = { 20, 4, 51 };
            //得到数组中大于50的数
            IEnumerable ie = arr.Select(p => p).Where(p => p > 50);
            //输出
            IEnumerator result = ie.GetEnumerator();
            while (result.MoveNext())
            {
                Response.Write(result.Current);
            }


(1)、IEnumerable接口,只包含一个抽象的方法GetEnumerator(),它返回一个可用于循环访问集合的IEnumerator对象。

(2)、IEnumerator 集合访问器,没有它,就不能使用foreach语句遍历集合或数组。

       IEnumerator接口定义了一个Current属性,MoveNext和Reset两个方法。
           Current属性,来获取当前集合中的项吧。
           MoveNext方法只是将游标的内部位置向前移动(就是移到一下个元素而已),要想进行循环遍历,不向前移动一下怎么行呢?



二、拓展方法:对现有类提供额外的方法,增强类的功能。
              拓展方法是静态方法,必须写在静态类中。

    //拓展类只能是静态类
    public static class ExtraClass
    {
        //string的拓展方法--特殊的静态方法(this表示为string类型添加特殊的方法ToPascal)
        public static string ToPascal(this string s)
        {
            return s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower();
        }
        //IEnumerable的拓展方法
        public static string Print(this IEnumerable<int> ie)
        {
            string str = "";
           IEnumerator<int> result= ie.GetEnumerator();
           while (result.MoveNext())
           {
               
               str+=result.Current+"|";  
           }
           return str;
        }
    }


            string str = "werwerwerw";
            Console.WriteLine(str.ToPascal());



三、Lambda表达式:没有参数的匿名方法
    历史:FrameWork1.0 委托---->FrameWork2.0 匿名方法--->FrameWork3.5 匿名方法--->Lambda表达式
1、FrameWork1.0 委托

    public delegate string deleTransfer(string s);//注意方法的签名
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //委托指向方法名
            deleTransfer trans = new deleTransfer(ToPascal);
            Response.Write(trans("FrameWork1.0 委托"));
        }

        public string ToPascal(string s)
        {
            return s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower();
        }
    }

注:方法名可以随便

2、FrameWork2.0 匿名方法

    public delegate string deleTransfer(string s);
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            deleTransfer trans = delegate(string s){return s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower();};
            Response.Write(trans("FrameWork2.0 匿名方法"));
        }
    }

3、FrameWork3.5 匿名方法

    public delegate string deleTransfer(string s);
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            deleTransfer trans = (s)=>{return s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower();};
            Response.Write(trans("FrameWork3.5 匿名方法"));
        }
    }

4、Lambda表达式

    public delegate string deleTransfer(string s);
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {   //语法:(参数列表)=>{方法体};
            deleTransfer trans = s=>s.Substring(0, 1).ToUpper() + s.Substring(1).ToLower();
            Response.Write(trans("Lambda表达式"));
        }
    }

四、LINQ基本方法语法方式
1、select/where 语句

    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            List<string> persons = new List<string>();
            persons.Add("zhang shan");
            persons.Add("zhang shan feng");
            persons.Add("li si");
            persons.Add("wang wu");
            //查询名称以zhang开头
            //var result = (from p in persons select p).Where(p => p.StartsWith("zhang"));
            var result = persons.Select(p => p).Where(p => p.StartsWith("zhang"));
            Label1.Text = result.Print();
        }
    }

    //拓展类只能是静态类
    public static class ExtraClassA
    {
        //IEnumerable的拓展方法
        public static string Print(this IEnumerable<string> ie)
        {
            string str = "";
            IEnumerator<string> result = ie.GetEnumerator();
            while (result.MoveNext())
            {

                str += result.Current + "|";
            }
            return str;
        }
    }

2、OrderBy排序

            //var result = persons.OrderBy(p => p);
            //按名字最后一个字母排序
            var result = persons.OrderBy(p => p.Substring(p.Length - 1, 1));
            //降序
            var result=persons.OrderByDescending(p=>p)


3、GroupBy分组

            List<string> persons = new List<string>();
            persons.Add("zhang shan");
            persons.Add("zhang shan feng");
            persons.Add("li si");
            persons.Add("wang wu");
            //按姓名分组,取出姓名中空格前的部分
            var result = persons.GroupBy(p => p.Split(new char[] { ' ' })[0]);
            foreach (var group in result)//外层循环得到分组            
            {
                Response.Write("姓:" + group.Key + "<br>");
                foreach (var name in group)//内层循环得到分组中的项               
                {
                    Response.Write(" " + name + "<br>");
                }
            }

 

 

LINQ 的更多资源
官方网站
http://msdn2.microsoft.com/zh-cn/netframework/aa904594(en-us).aspx
Hooked On LINQ
http://www.hookedonlinq.com/



五、高级查询方法

1、聚合类
Count,Max/Min,Average,Sum

//Count 返回集合项的数目
int count = (from p in foxRiver8
             where p.Age <= 30
             select p).Count();//混合模式

int count = foxRiver8
	.Where(p => p.Age <= 30)
	.Count();//纯粹查询方法模式


//Max 返回集合中的最大值
int maxAge = (from p in foxRiver8
	select p.Age).Max();

int maxAge = foxRiver8
	.Select(p => p.Age)
	.Max();


//Average 返回集合的平均值
double averageAge = (from p in foxRiver8
	select p.Age).Average();

double averageAge = foxRiver8
	.Select(p => p.Age)
	.Average();


//Sum 返回集合的总和
Int sumAge = (from p in foxRiver8
	select p.Age).Sum();

int sumAge = foxRiver8
	.Select(p => p.Age)
	.Sum();


2、排序类
ThenBy

//ThenBy 提供复合排序条件
var q = foxRiver8
	.OrderBy(p => p.FirstName)
    	.ThenBy(p => p.LasName)
    	.ThenBy(p => p.Age);//查询方法

var q = from p in foxRiver8
        orderby p.FirstName, p.LasName, p.Age
        select p;//查询语句


3、分区类
Take,TakeWhile,Skip,SkipWhile

Take 提取指定数量的项
Skip 跳过指定数量的项并获取剩余的项

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.Skip(1).Take(3);//跳过前1条记录,连续提取3条记录,得到 2 3 4

foreach (var item in q)
{
    Console.WriteLine(item);
}

TakeWhile 根据指定条件提取项
SkipWhile 根据指定条件跳过项

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.SkipWhile(i => i % 3 != 0)
    .TakeWhile(i => i % 2 != 0); 

foreach (var item in q)
{
    Console.WriteLine(item);
}


请判断以下代码输出结果是什么?请判断以下代码输出结果是什么?

int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var q = numbers.Skip(1).Take(3).Skip(1).Take(2);
foreach (var item in q)
{
    Console.WriteLine(item);
}


输出: 3  4


4、集合类
Distinct

//Distinct 去掉集合中的重复项 
int[] factorsOf300 = { 2, 2, 3, 5, 5 };

var uniqueFactors = factorsOf300.Distinct();//输出: 2 3 5


 


5、生成类
Range, Repeat

//Range 生成一个整数序列 var numbers =Enumerable.Range(1, 5); foreach (var item in numbers) {     Console.WriteLine(item);//12345 }

//Repeat 生成一个重复项的序列 var numbers =  Enumerable.Repeat(“Beijing 2008”, 2); foreach (var item in numbers) {     Console.WriteLine(item);//Beijing 2008Beijing 2008 }

 

 


生成类查询方法小结
使用生成类查询方法时,需要注意以下几点:
和其他几类方法不同,Range/Repeat 不是扩展方法,而是普通的静态方法
Range 只能产生整数序列
Repeat 可以产生泛型序列
所有的查询方法都存放在 System.Linq.Enumerable 静态类中 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tiz198183

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值