LINQ入门教程之各种标准查询操作符(二)
7. 聚合操作符
View Code
8. 集合操作符
View Code
9. 生成操作符
1 #region 生成操作符 即从现有序列的值中创建新的序列 2 /// <summary> 3 /// 返回一个指定类型的空集 4 /// </summary> 5 static void EmptyFunction() 6 { 7 string[] name1 = { "1","2" }; 8 string[] name2={"3","4","5"}; 9 string[] name3 = { "3", "7", "8", "9" }; 10 List<string[]> strlists=new List<string[]>{name1,name2,name3}; 11 //无符合条件,返回空集合 12 IEnumerable<string> nameslist = strlists.Aggregate(Enumerable.Empty<string>( ), 13 (current, next) => next.Length > 5? current.Union(next) : current); 14 15 foreach (string item in nameslist) 16 { 17 Console.WriteLine(item); 18 } 19 } 20 /// <summary> 21 /// 创建一个包含数字序列的集合 包含两个参数,第一个参数是作为序列开始的整数值,第二个参数是要产生的整数序列中数字的个数 22 /// </summary> 23 static void RangeFunction() 24 { 25 IEnumerable<int> intAry = Enumerable.Range(2, 5); 26 foreach (int item in intAry) 27 { 28 Console.Write(item + " "); 29 } 30 }//output: 2 3 4 5 6 31 /// <summary> 32 /// Repeat 操作符创建一个单值序列,将此值重复一定的次数 33 /// </summary> 34 static void RepeatFunction() 35 { 36 IEnumerable<string[]> strAry = Enumerable.Repeat(new string[]{"world","hello"}, 2); 37 foreach (string[] item in strAry) 38 { 39 Console.WriteLine(item[1] +" "+item[0] ); 40 } 41 } 42 //outpupt: 43 //hello world 44 //hello world 45 #endregion
10. 转换操作符
1 #region 转换操作符 将输入对象的类型转变为序列的动作 2 /// <summary> 3 /// 将查询的输入以IEnumerable<Of T>类型返回 4 /// </summary> 5 static void AsEnumerableFunction() 6 { 7 DataContext context = new DataContext(StaticData.ConnectSql); 8 Table<Contact> contacts = context.GetTable<Contact>(); 9 //使用AsEnumerable操作符将类型自带的Where方法替换为标准查询操作符Where的方法 10 //这里的Where方法 区分查询条件的大小写, 11 //如果用“G”,只能查询出‘G’开头的Firstname,若换做"g",可以查询出所有以g/G开头的Firstname 12 IEnumerable<Contact> query = contacts.AsEnumerable().Where(con=>con.FirstName.Contains("g")); 13 foreach (Contact item in query) 14 { 15 Console.Write(item.FirstName + " "); 16 } 17 //这里的Where方法 不区分查询条件的大小写 用g/G都可以 18 IEnumerable<Contact> query2 = contacts.Where(con => con.FirstName.Contains("G")); 19 Console.WriteLine(""); 20 foreach (Contact item in query2) 21 { 22 Console.Write(item.FirstName + " "); 23 } 24 } 25 //output: 26 //Gong 27 //Gong gong1 gong2 gong3 gong4 28 /// <summary> 29 /// 将IEnumerable集合中的元素转换为某种指定的类型 30 /// </summary> 31 static void CastFunction( ) 32 { 33 //ArrayList并不实现IEnumerable(Of T) 34 ArrayList names = new ArrayList( ); 35 var repeatlist = Enumerable.Range(1, 10); 36 foreach (int item in repeatlist) 37 { 38 names.Add(item); 39 } 40 //通过使用Cast操作符,可以使用标准查询操作符来查询此序列 41 IEnumerable<int> query=names.Cast<int>().Select(name=>name); 42 foreach (int item in query) 43 { 44 Console.Write(item +" "); 45 } 46 } 47 //output: 48 //1 2 3 4 5 6 7 8 9 10 49 /// <summary> 50 /// 实现一个基于特定的类型对IEnumerable对象的元素进行过滤 51 /// </summary> 52 static void OfTypeFunction() 53 { 54 ArrayList names = new ArrayList(7); 55 names.Add("hello"); 56 names.Add("thank you"); 57 names.Add(2); 58 names.Add(4); 59 names.Add("yy"); 60 names.Add(6); 61 //oftype方法返回序列中可以转为int型的元素,通过在IEnumerable对象上使用OfType操作符,就可以使用标准查询操作符来查询此序列 62 IEnumerable<int> query = names.OfType<int>(); 63 foreach (int item in query) 64 { 65 Console.Write(item+ " "); 66 } 67 } 68 //output: 69 //2 4 6 70 /// <summary> 71 /// 用于实现从一个IEnumerable序列创建一个数组 ,ToArray会强制查询立即执行 72 /// </summary> 73 static void ToArrayFunction() 74 { 75 DataContext context = new DataContext(StaticData.ConnectSql); 76 Table<Contact> contacts = context.GetTable<Contact>(); 77 var query = contacts.Select(con => con.FirstName).ToArray(); 78 foreach (string item in query) 79 { 80 Console.Write(item+" "); 81 } 82 } 83 //output:Gond gong2 gong3 gong4 gong5 84 /// <summary> 85 /// ToDictionary操作符将序列中的所有返回元素插入到一个Dictionary(Of TKey,TValue)对象中,会强制查询立即执行 86 /// </summary> 87 static void ToDictionaryFunction() 88 { 89 DataContext context = new DataContext(StaticData.ConnectSql); 90 Table<Contact> contact = context.GetTable<Contact>( ); 91 Dictionary<string, Contact> dict = contact.Where(con=>con.FirstName.Contains("2")).ToDictionary(con => con.FirstName); 92 foreach (KeyValuePair<string,Contact> item in dict) 93 { 94 Console.WriteLine(item.Key+" "+item.Value.MiddleName); 95 } 96 } 97 //output: 98 //gong2 wen2 99 /// <summary> 100 /// 将一个IEnumerable序列集合转换为一个List(Of T)对象,它也会强制查询立即执行 101 /// </summary> 102 static void ToListFunction( ) 103 { 104 DataContext context = new DataContext(StaticData.ConnectSql); 105 Table<Contact> contact = context.GetTable<Contact>(); 106 IEnumerable<string> query = (from c in contact where c.FirstName.Contains("2") select c.FirstName).ToList(); 107 foreach (string item in query) 108 { 109 Console.WriteLine(item); 110 } 111 } 112 //output: gong2 113 /// <summary> 114 /// 基于一个特定的主键,将返回的元素放置到一个Lookup(Of Tkey,TElement)对象中 115 /// Lookup是主键的集合,每个主键都映射到一个或多个值上,可以认为Lookup对象是一个一对多的字典 116 /// </summary> 117 static void ToLookupFunction() 118 { 119 DataContext context = new DataContext(StaticData.ConnectSql); 120 Table<Contact> contact = context.GetTable<Contact>(); 121 //Title作为key,Middelname和lastanem作为Element, key对应多个Element 122 ILookup<string, string> lkp = contact.ToLookup(con => con.Title, con => con.MiddleName + con.LastName); 123 foreach (IGrouping<string,string> item in lkp) 124 { 125 Console.WriteLine(item.Key); 126 foreach (string subitem in item) 127 { 128 Console.WriteLine(" "+subitem); 129 } 130 } 131 } 132 //output: 133 //xinwen2 134 // wentao 135 // wenstaos 136 //xinwen 137 // wen2tao2 138 // wen3tao3 139 // wen4tao4 140 // wen5tao5 141 #endregion
11. 元素操作符
#region 元素操作符 从一个序列返回单个特定的元素 /// <summary> /// 将一个空集合替换为包含默认的单个值得集合 /// </summary> static void DefaultIfEmptyFunction() { DataContext context = new DataContext(StaticData.ConnectSql); Table<Contact> contacts = context.GetTable<Contact>(); //必须指定类型,用var在foreach时会报错 IEnumerable<Contact> query=from con in contacts where con.FirstName.StartsWith("gg") select con; Contact defaultContact = new Contact() { FirstName="test",MiddleName="defaultIfEmpty"}; foreach (Contact item in query.DefaultIfEmpty(defaultContact)) //foreach (string item in query.DefaultIfEmpty("none")) { Console.Write(item.FirstName+" "+item.MiddleName); } } //output: //test defaultIfEmpty /// <summary> /// ElementAt返回集合中给定索引处的元素。集合是零基(索引从0开始计)的,返回值是数据源中特定位置的元素 /// ElementAtOrDefault 将ElementAt操作符和DefaultIfEmpty操作符的部分功能结合在一起,返回在某一特定处的元素,如果索引超出范围则返回默认值 /// </summary> static void ElementAtFunction() { DataContext context = new DataContext(StaticData.ConnectSql); Table<Contact> contacts = context.GetTable<Contact>( ); IEnumerable<string> query = from c in contacts where c.FirstName.StartsWith("G") select c.FirstName; Console.WriteLine(query.ElementAt(0)); try { query.ElementAt(10000); } catch (Exception ex) { Console.WriteLine("error:"+ex.Message); } //超出索引范围 返回默认值 Console.WriteLine(query.ElementAtOrDefault(10000)); } //output: //Gong //"error:"+指定的参数已超出有效值的范围 //参数名:index /// <summary> /// First查询集合中符合条件的第一个元素 Last查询集合中符合条件的最后一个元素 ,若没有发现任何元素抛出异常 /// FirstDefault 和LastDefualt,若没有发现任何元素则返回默认值 /// </summary> static void FirstLastFunction() { DataContext context = new DataContext(StaticData.ConnectSql); Table<Contact> contacts = context.GetTable<Contact>(); IEnumerable<Contact> query = from c in contacts select c; Contact model = new Contact() {FirstName="test" }; model = query.First(); //输出 gong Console.WriteLine("First:" + model.FirstName); //输出 gong model = query.FirstOrDefault(); Console.WriteLine("FirstDefault" + model.FirstName); try { model = query.Last(con => con == null); Console.WriteLine("Last:" + model.FirstName); } catch (Exception ex) { //在query.Last处报错,error:序列不包含任何匹配元素 Console.WriteLine("Last error"+ex.Message); } model = query.LastOrDefault(con => con == null); try { Console.WriteLine("LastDefault:" + model.FirstName); } catch (Exception ex) { //在调用model时报错,error:未将对象引用设置到对象的实例 Console.WriteLine("LastDefault Error:"+ex.Message); } } /// <summary> /// Single操作符从一个序列中返回单个元素,或唯一满足某一特定条件的元素,如果包含一个以上或没有发现元素则抛出异常 /// SingleOrDefault从一个序列中返回单个元素,如果没有发现元素会返回一个默认值,如果返回多个元素,则抛出异常 /// </summary> static void SingleFunction( ) { DataContext context = new DataContext(StaticData.ConnectSql); Table<Contact> contacts = context.GetTable<Contact>( ); IEnumerable<string> quuery = contacts.Where(con => con.FirstName.Equals("Gong2")).Select(con => con.FirstName); Console.WriteLine("single:"+quuery.Single()); IEnumerable<string> query2 = contacts.Where(con => con.FirstName.Equals("test")).Select(con => con.FirstName); Console.WriteLine("single default:"+query2.SingleOrDefault()); } //output: //single:gong2 //single default: #endregion
12. 相等操作符
1 #region 相等操作符 2 /// <summary> 3 /// SequenceEqual 通过比较两个序列来检查他们相应的元素是否相同,如果序列有相同数量的元素,并且对应元素的值相同,则返回true,否则返回false 4 /// </summary> 5 static void SequenceEqualFunction() 6 { 7 int[] numbers1 = { 1, 2, 3, 4, 5, 6, 7 }; 8 int[] numbers2 = { 1, 2, 3, 4, 5, 6, 7 }; 9 int[] numbers3 = { 1, 2, 3, 4, 5, 7, 6}; 10 bool flag = numbers1.SequenceEqual(numbers2); 11 Console.WriteLine(flag); 12 flag = numbers1.SequenceEqual(numbers3); 13 Console.WriteLine(flag); 14 } 15 //output: 16 //True 17 //False 18 #endregion
13. 量词操作符
1 #region 量词操作符 返回一个Boolean值,指示序列中是否存在部分或全部元素符合某个特定的条件 2 /// <summary> 3 ///All 判定在集合中是否所有的值都满足特定的条件,返回值是boolean类型。如果满足,返回true,否则 false。 4 /// </summary> 5 static void AllFunction() 6 { 7 Contact[] contacts = { new Contact{FirstName="gwt"} 8 ,new Contact{FirstName="gwt1"} 9 ,new Contact{FirstName="gwt2"} 10 ,new Contact{FirstName="gwt3"} 11 ,new Contact{FirstName="gwt4"} 12 ,new Contact{FirstName="lining"}}; 13 bool flag = contacts.All(name => name.FirstName.StartsWith("gwt")); 14 Console.WriteLine("All:"+flag); 15 flag = contacts.Any(name => name.FirstName.StartsWith("gwt")); 16 Console.WriteLine("Any:"+flag); 17 IEnumerable<string> query = contacts.Select(name => name.FirstName); 18 flag = query.Contains("gwt"); 19 Console.WriteLine("Contains:"+flag); 20 } 21 //output: 22 //All:False 23 //Any:True 24 //Contains:True 25 #endregion
14. 分割操作符
1 #region 分割操作符 是指将一个单一的输入序列划分成两个或多个部分或序列 ,同时不会对输入元素重排序,然后返回一个新形成的部分 2 /// <summary> 3 /// Skip: 跳过一些元素 到达序列中一个特定的位置 4 /// SkipWhile只要特定的条件为真,就继续略过元素,直到出现条件不满足时,返回剩余的元素,剩余的元素不再做判断。 5 /// </summary> 6 static void SkipFunction() 7 { 8 IEnumerable<int> query = Enumerable.Range(1, 10); 9 IEnumerable<int> query2 = query.Skip(5); 10 Console.WriteLine("Skip"); 11 foreach (int item in query2) 12 { 13 Console.Write(item + " "); 14 } 15 Console.WriteLine(); 16 Console.WriteLine("SkipWhile"); 17 //条件为num>5, 满足大于5的数被略过,query 为5 4 3 2 1 18 //如果条件为num<5 ,则query集合为10,9,8,7,6,5,4,3,2,1(因为第一个10<5为false,剩余元素不再做判断)这是一个坑啊,弄了半天才整明白 19 IEnumerable<int> query3 = (from n in query orderby n descending select n ).SkipWhile(num=>num>5); 20 foreach (int item in query3) 21 { 22 Console.Write(item+" "); 23 } 24 query3 = (from n in query orderby n descending select n).SkipWhile(num => num < 5); 25 Console.WriteLine(); 26 foreach (int item in query3) 27 { 28 Console.Write(item + " "); 29 } 30 } 31 //output: 32 //6 7 8 9 10 33 //5 4 3 2 1 34 /// <summary> 35 /// 返回某个序列中连续的元素子序列,子序列开始于原序列的开头,结束于某个指定的位置。 36 /// Take :从序列的开头返回指定数量的连续元素 37 /// TakeWhile:只要满足指定的条件,就会返回序列的元素,一旦出现条件不满足,查询不会继续下去,即使后面有满足条件的元素。 38 /// </summary> 39 static void TakeFunction() 40 { 41 int[] randomNumbers = { 86,2,77,94,100,65,5,22,70,55,81,66,45}; 42 IEnumerable<int> takeTopFour = randomNumbers.OrderByDescending(num => num).Take(4); 43 Console.Write("Take:"); 44 foreach (int item in takeTopFour) 45 { 46 Console.Write(item + " "); 47 } 48 Console.WriteLine(); 49 Console.Write("TakeWhile:"); 50 IEnumerable<int> takeGreaterThan50=(from n in randomNumbers orderby n select n).TakeWhile(n=>n<50); 51 foreach (int item in takeGreaterThan50) 52 { 53 Console.Write(item+" "); 54 } 55 } 56 //output: 57 //Take:100 94 86 81 58 //TakeWhile:2 5 22 45 59 #endregion
最后出一个使用查询操作符的例子
1 #region 使用查询操作符 2 static void UseSearchOperate() 3 { 4 DataContext context = new DataContext(StaticData.ConnectSql); 5 Table<Contact> contacts = context.GetTable<Contact>(); 6 Table<Employee> employees = context.GetTable<Employee>(); 7 //使用查询语法 8 var query = from con in contacts 9 join emp in employees on con.ContactID equals emp.ContactID 10 where con.FirstName.StartsWith("gong2") 11 && emp.HireDate.Year > 2012 12 orderby con.FirstName 13 orderby con.LastName 14 select new { emp.EmployeeID, con.LastName, con.FirstName, emp.Title, con.EmailAddress, emp.HireDate }; 15 //使用方法语法 16 var query2 = contacts.Join(employees, con => con.ContactID, emp => emp.ContactID, (con, emp) => new { con = con, emp = emp }) 17 .Where(c => c.con.FirstName.StartsWith("gong2")) 18 .Where(c => c.emp.HireDate.Year > 2012) 19 .OrderBy(c => c.con.FirstName) 20 .ThenBy(c => c.con.LastName) 21 .Select(o=>new {o.con.FirstName,o.con.LastName,o.con.EmailAddress,o.emp.EmployeeID,o.emp.Title,o.emp.HireDate}); 22 foreach (var item in query2) 23 { 24 Console.WriteLine(item.FirstName + " " + item.HireDate + " " + item.EmailAddress); 25 } 26 } 27 //output: 28 //gong2 2013-08-01 97182234@qq.com 29 //gong2 2013-08-01 97182234@qq.com 30 //gong2 2013-08-01 97182234@qq.com 31 //gong2 2013-08-01 97182234@qq.com 32 #endregion
动动您的手指,点下支持,您的支持是我最大动力!