zoukankan      html  css  js  c++  java
  • Linq学习之关键字

     

    书写Linq时,分为方法语法和查询表达式两种语法方式。

    这里假设你对Lambda表达式,匿名类型,静态扩展方法 有一定的认识。

    以下,对Linq中的部分关键字进行介绍。

    学习过程中,主要参考了 http://www.cnblogs.com/goscan/archive/2011/05/05/Linq_study_log.html 一文,在这里表示对作者进行感谢。

    From关键字 

    使用From时,From后跟数据源的一个变量,in 后指定数据源。数据源的类型必须是实现IEnumerable<T>,如果仅仅实现了IEnumerable类型可以通过Cast<T>方法来转换

    示例代码

     1         //from 的Container必须是IEnumerable<T> 类型
     2         public void StudyFrom()
     3         {
     4 
     5             //IEnumerable<BookMarker> query = from bm in Container select bm;
     6             string[] array = new string[] { "fa", "dsfsa", "fdsaf" };
     7             IEnumerable<string> res = from s in array select s;//数组可以
     8             ArrayList al = new ArrayList() { "fds", "dsaf", "fdsa" };//ArrayList并没有实现IEnumerable<T>
     9             IEnumerable<string> data = al.Cast<string>();//可以转换为IEnumerable<T>类型
    10         }

    Select关键字

    Select可以看做事对查询结果的投影,类似与SQL中查询出来的新表,在这里是新的对象。

    可以对新的对象进行重组(查询结果的投影),生成新的对象。

    示例代码

            //select 是对查询结果的投影
            //
            public void StudySelect()
            {
                //将结果投影到一个匿名类型上
                var bs = from p in Container select new { p.Name, p.Value };
                //将投影结果进行计算重组
                var bs2 = from b in Container
                          select new
                                     {
                                         Name = b.Name,
                                         Tag = b.Category + "$" + b.Tag
                                     };
                var bs3 = Container.Select(p => new { Name = p.Name, Tag = p.Category + "$" + p.Tag });//利用Lambda查询
            }

    Join关键字

    Join关键字稍显复杂。格式如下

     From a in aSet join b in bSet  on a.ID equals b.ID select new{a,b}

     或者

    From a in aSet join b in bSet on value1 equals value2 select *****

    或者

     From a in aSet join b in bSet on Func1() equals Func2() select ***

    方法语法的格式为

    aSet.Join(bSet , 获得判等左值的委托,获得判等右值的委托,查询结果投影委托 )

    例如 aSet.Join(bSet,a=>a.ID,b=>b.ID,(a,b)=>new {a,b})

    示例代码

            /// <summary>
            /// Join方法 from a in aSet join b in bSet on a.Id equals b.Id select new { a,b}
            /// from a in aSet join b in bSet on value1 equals value2 ……
            /// from a in aSet join b in bSet on Func1() equals
            /// 操作符号需要是equals 或者not equals 
            /// Join方法 ( 第二个需要连接的数据源,表达式1,表达式2,输出结果 ) 表达式1会默认和表达式2相等最为连接条件
            /// </summary>
            public void StudyJoin()
            {
                string[] indexs = new string[] { "1", "2", "6", "9" };
                var res = from i in indexs
                          join b in Container
                              on "ID-" + i equals b.ID
                          select new string[] { i, b.Name };
                foreach (string[] strings in res)
                {
                    Console.WriteLine(string.Format("index->{0},value-{1}", strings[0], strings[1]));
                }
    
                var res2 = indexs.Join(Container, i => "ID-" + i, c => c.ID, (i, c) => new { i, c });//函数式查询
                foreach (var item in res2)
                {
                    Console.WriteLine(item.i + "==>" + item.c.Name);
                }
            }

    Group关键字

    Group关键字表示对数据源进行分组,使用GroupBy组合,Group后跟数据源,by后跟分组依据,into 表示将分组结果存放到的变量,该变量会默认有一个Key属性,即为by 的依据(组别),该变量类型是IGrouping<TKey,TElement>类型,所以查出来就是IGrouping的一个集合。如果想要访问其中的元素,需要使用两层ForEach进行遍历。

    示例代码

            /// <summary>
            /// Group将对查询结果进行分组,使用Group By 组合,group后边跟为哪个对象分组,by后边跟上分组的依据
            /// 分组完成需要使用into将分组后的结果放在一个变量中
            /// 访问该变量的Key属性可以得到组别
            /// </summary>
            public void StudyGroup()
            {
                var res = from bookMarker in Container
                          group bookMarker by bookMarker.ID.Length
                              into bg
                              select new { bg.Key, bg };
                
                res.ToList().ForEach
                    (
                        item =>
                            {
                                Console.WriteLine(string.Format("Key:{0},----", item.Key));
                                item.bg.ToList().ForEach(
                                    bookmarker => Console.WriteLine(string.Format("ID:{0},Name:{1}", bookmarker.ID, bookmarker.Name)));
                            }
    
                    );
            }

    Let关键字

    Let关键字允许在查询过程中,自定一个一个变量,供使用。

    示例代码

            /// <summary>
            /// let运行在查询过程中,自定义一个变量,供使用
            /// </summary>
            public void StudyLet()
            {
                var query = from bookmarker in Container
                            let Type = "书签"
                            select new
                                       {
                                           Type = Type,
                                           Name = bookmarker.Name,
                                           Url = bookmarker.Value
                                       };
                foreach (var VARIABLE in query)
                {
                    Console.WriteLine(string.Format("书签名{0},地址是{1}。类型为{2}", VARIABLE.Name, VARIABLE.Url, VARIABLE.Type));
                }
            }

    Take和Skip关键字

    Skip表示跳过集合的若干个元素,Take表示从当前集合的开始处取N个元素

    示例

            public void StudyTakeSkip()
            {
                var query = from bookmarker in Container select bookmarker;
               IEnumerable<BookMarker> source=   query.Skip(2).Take(6);
                Printer<BookMarker>.ConPrint( source, item=>string.Format( "名字:{0}ID:{1}",item.Name,item.ID ) );
            }

    Yield关键字

    Yield关键字可以使得查询延迟加载。也就是在使用到该数据时,在进行数据的添加或者访问。但是如果使用了聚合函数,例如MAX,OrderBy,等,该特性竟会失效,将遍历所有元素。

    示例代码

    将会发生死循环。

            //LazyLoad示例
    
            //yield 关键字可以使得 查询时延迟加载,即使用是再向数据容器中添加数据
            public static  IEnumerable<int> InitData()
            {
                int i = 0;
                while (true)
                {
                    yield return i++;
                }
            }
    
    
            public void LazyLoad()
            {
                var query = from i in InitData() select i;
                Printer<int>.ConPrint(query.Take(10),item=>item.ToString());
            }
    
            public void CannotLazyLoad()
            {
                var query = from i in InitData() select i;
                Printer<int>.ConPrint(query.OrderBy(item=>item).Take(10),item=>item.ToString());//使用OrderBy时,会尝试遍历所有元素,故会无限循环
    
            }

    之下是DataContainer.cs

        public class DataContainer
        {
            public static List<BookMarker> BookMarkers { get; set; } 
    
           static DataContainer()
            {
                InitBookMarkers();
            }
    
            static private void InitBookMarkers()
            {
                BookMarkers=new List<BookMarker>();
                for (int i = 0; i < 20; i++)
                {
                    BookMarker b=new BookMarker()
                                     {
                                         ID = string.Format("ID-{0}",i),
                                         Name = string.Format("Name-{0}",i),
                                         Category = string.Format("Category-{0}",i),
                                         Tag = string.Format("Tag-{0}",i),
                                         Value=string.Format("Value-{0}",i)
                                     };
                    BookMarkers.Add(b);
                }
                
            }
        }
    
        public class  BookMarker
        {
            public string Name { get; set; }
            public string ID { get; set; }
            public string Category { get; set; }
            public string Tag { get; set; }
            public string Value { get; set; }
        }

     Printer.cs

        public class Printer<T>
        {
            public static void ConPrint<T>(IEnumerable<T> source,Func<T,string> toStrFunc  )
            {
                foreach (T t in source)
                {
                    Console.WriteLine( toStrFunc(t) );
                }
            }
        }

    Program.cs

            static void Main(string[] args)
            {
                KeyWordsStudy keyWordsStudy=new KeyWordsStudy();
                //keyWordsStudy.StudyJoin();
                //keyWordsStudy.StudyLet(); 
                keyWordsStudy.StudyGroup();
                keyWordsStudy.StudyTakeSkip();
                //keyWordsStudy.LazyLoad();
                //keyWordsStudy.CannotLazyLoad();会抛出内存溢出的异常,应为orderby的存在,导致 试图遍历所有成员//Console.WriteLine("结束");
                Console.ReadKey();
    
            }
  • 相关阅读:
    转:backbone.js源码解析:extend、Backbone.View
    转:前端单元测试总结
    转:JavaScript Promises相当酷:一种有趣的方案库
    npm发布模块
    转:nodejs npm常用命令
    nodejs守护进程forever
    转:SublimeText2 快捷键一览表
    转载7 Essential JavaScript Functions
    用node生成svg图片
    关于performance
  • 原文地址:https://www.cnblogs.com/linecheng/p/2562669.html
Copyright © 2011-2022 走看看