LINQ,语言集成查询(Language Integrated Query)是一组用C#和Visual Basic语言的扩展。
对于编写查询的开发人员来说,LINQ 最明显的“语言集成”部分是查询表达式。查询表达式是使用 C# 3.0 中引入的声明性查询语法编写的。通过使用查询语法,你甚至可以使用最少的代码对数据源执行复杂的筛选、排序和分组操作。你使用相同的基本查询表达式模式来查询和转换 SQL 数据库、ADO.NET 数据集、XML 文档和流以及 .NET 集合中的数据。
下面我们通过一些实际中常用的功能举例来学习一下。
1.简单数组的一些基本操作
查询数组中大于80的分数。
1 int[] scores = new int[] { 97, 92, 81, 60 }; 2 3 IEnumerable<int> scoreQuery = from score in scores 4 where score > 80 5 select score;6 7 foreach(int score in scoreQuery) 8 { 9 Console.WriteLine(score); 10 }
查询数组中大于80的分数,按照升序ascending排列(默认为降序descending ),并且格式化结果。
1 int[] scores = new int[] { 97, 92, 81, 60 }; 2 3 IEnumerable<string> scoreQuery = from score in scores 4 where score > 80 5 orderby score ascending 6 select String.Format("Score: {0}",score); 7 8 foreach(string score in scoreQuery) 9 { 10 Console.WriteLine(score); 11 }
2.数组列表的一些基本操作
这里首先创建一个程序员Programer类,包含了ID,Name,Age,Language属性。
1 public class Programer 2 { 3 public int ID; 4 public string Name; 5 public int Age; 6 public string Language; 7 }
然后创建一个Programer类型的测试数组列表。查找编程语言使用C#的程序员。结果将输出Name1和Name4。
1 Programer[] programers = new Programer[]{ 2 new Programer{ID=1,Name="Name1",Age=25,Language="C#"}, 3 new Programer{ID=2,Name="Name2",Age=28,Language="Visual Basic"}, 4 new Programer{ID=3,Name="Name3",Age=30,Language="C++"}, 5 new Programer{ID=4,Name="Name4",Age=30,Language="C#"}, 6 new Programer{ID=5,Name="Name5",Age=35,Language="C"} 7 }; 8 9 IEnumerable<Programer> programerQuery = 10 from p in programers 11 where p.Language == "C#" 12 select p; 13 14 foreach(var item in programerQuery) 15 { 16 Console.WriteLine(item.Name); 17 }
同样,这里也可以根据需要进行排序,对结果格式化等操作。下面查找编程语言使用C#的程序员,按Age升序排列,结果格式化输出Name和Age。
1 Programer[] programers = new Programer[]{ 2 new Programer{ID=1,Name="Name1",Age=25,Language="C#"}, 3 new Programer{ID=2,Name="Name2",Age=28,Language="Visual Basic"}, 4 new Programer{ID=3,Name="Name3",Age=30,Language="C++"}, 5 new Programer{ID=4,Name="Name4",Age=30,Language="C#"}, 6 new Programer{ID=5,Name="Name5",Age=35,Language="C"} 7 }; 8 9 IEnumerable<string> programerQuery = 10 from p in programers 11 where p.Language == "C#" 12 orderby p.Age ascending 13 select String.Format("Name: {0} , Age: {1}", p.Name, p.Age); 14 15 foreach(var item in programerQuery) 16 { 17 Console.WriteLine(item); 18 }
对于查询的结果,我们还可以根据需要选取部分数据。下面我们只需要程序员列表中的Name和Language数据。
1 Programer[] programers = new Programer[]{ 2 new Programer{ID=1,Name="Name1",Age=25,Language="C#"}, 3 new Programer{ID=2,Name="Name2",Age=28,Language="Visual Basic"}, 4 new Programer{ID=3,Name="Name3",Age=30,Language="C++"}, 5 new Programer{ID=4,Name="Name4",Age=30,Language="C#"}, 6 new Programer{ID=5,Name="Name5",Age=35,Language="C"} 7 }; 8 9 var newProgramers = from p in programers 10 select new 11 { 12 Name = p.Name, 13 Language = p.Language 14 }; 15 16 foreach(var item in newProgramers) 17 { 18 Console.WriteLine("Name: {0} , Language: {1}", item.Name, item.Language); 19 }
当我们需要知道每种编程语言都有哪些程序员,我们就需要用到Group分组功能。
1 Programer[] programers = new Programer[]{ 2 new Programer{ID=1,Name="Name1",Age=25,Language="C#"}, 3 new Programer{ID=2,Name="Name2",Age=28,Language="Visual Basic"}, 4 new Programer{ID=3,Name="Name3",Age=30,Language="C++"}, 5 new Programer{ID=4,Name="Name4",Age=30,Language="C#"}, 6 new Programer{ID=5,Name="Name5",Age=35,Language="C"} 7 }; 8 9 var programerGroupByLanguage = from p in programers 10 group p by p.Language; 11 12 foreach (var group in programerGroupByLanguage) 13 { 14 Console.WriteLine("Group: {0}", group.Key); 15 foreach(var item in group) 16 { 17 Console.WriteLine(item.Name); 18 } 19 Console.WriteLine(); 20 }
当我们想计算有多少程序员知道某种开发语言。在使用Group子句对开发语言进行分组后,可以使用Into子句将Group的子句结果存储在临时变量中。之后可以使用此变量来执行其他查询。
1 Programer[] programers = new Programer[]{ 2 new Programer{ID=1,Name="Name1",Age=25,Language="C#"}, 3 new Programer{ID=2,Name="Name2",Age=28,Language="Visual Basic"}, 4 new Programer{ID=3,Name="Name3",Age=30,Language="C++"}, 5 new Programer{ID=4,Name="Name4",Age=30,Language="C#"}, 6 new Programer{ID=5,Name="Name5",Age=35,Language="C"} 7 }; 8 9 var programerGroupByLanguage = from p in programers 10 group p by p.Language into languageGroup 11 select new 12 { 13 Language = languageGroup.Key, 14 Count = languageGroup.Count() 15 }; 16 17 foreach (var group in programerGroupByLanguage) 18 { 19 Console.WriteLine("Language {0} have {1} programers", group.Language, group.Count); 20 }
3.多个数组列表的一些基本操作
创建两个类,Product产品类和Category类别类,每个产品分配一个类别。
1 public class Category 2 { 3 public int CategoryID { get; set; } 4 public string CategoryName { get; set; } 5 } 6 7 public class Product 8 { 9 public int ProductID { get; set; } 10 public string ProductName { get; set; } 11 public int CategoryID { get; set; } 12 public string Description { get; set; } 13 }
接着创建一些Category类型和Product类型的测试数组列表。
下面我们按类别查询所有产品。
1 Category[] categories = new Category[]{ 2 new Category{CategoryID=1,CategoryName="TOYOTA"}, 3 new Category{CategoryID=2,CategoryName="BMW"}, 4 new Category{CategoryID=3,CategoryName="BENZ"}, 5 new Category{CategoryID=4,CategoryName="HONDA"}, 6 new Category{CategoryID=5,CategoryName="LEXUS"} 7 }; 8 9 Product[] products = new Product[]{ 10 new Product{ProductID=1,ProductName="Car1",CategoryID=1,Description="TOYOTA Car"}, 11 new Product{ProductID=2,ProductName="Car2",CategoryID=1,Description="TOYOTA SUV"}, 12 new Product{ProductID=3,ProductName="Car3",CategoryID=2,Description="BMW Car"}, 13 new Product{ProductID=4,ProductName="Car4",CategoryID=2,Description="BMW SUV"}, 14 new Product{ProductID=5,ProductName="Car5",CategoryID=3,Description="BENZ Car"}, 15 new Product{ProductID=6,ProductName="Car6",CategoryID=4,Description="HONDA Car"}, 16 new Product{ProductID=7,ProductName="Car7",CategoryID=5,Description="LEXUS Car"}, 17 new Product{ProductID=8,ProductName="Car8",CategoryID=5,Description="LEXUS SUV"} 18 }; 19 20 var productByCategoryResult1 = from c in categories 21 join p in products 22 on c.CategoryID equals p.CategoryID 23 select new 24 { 25 c.CategoryName, 26 p.ProductName, 27 p.Description 28 }; 29 30 var productByCategoryResult2 = from c in categories 31 from p in products 32 where c.CategoryID ==p.CategoryID 33 select new 34 { 35 c.CategoryName, 36 p.ProductName, 37 p.Description 38 }; 39 40 Console.WriteLine("Result 1:"); 41 foreach(var item in productByCategoryResult1) 42 { 43 Console.WriteLine(item); 44 } 45 46 Console.WriteLine("Result 2:"); 47 foreach (var item in productByCategoryResult2) 48 { 49 Console.WriteLine(item); 50 }
我们看到使用多个from和使用join查询出的结果是一样的。
当我们需要统计每种类别下的产品时,也就是对类别进行分组,只需加上into到某个变量语句即可,此时这个变量将自动对产品的结果集进行分组。
1 var productByCategoryResult = from c in categories 2 join p in products 3 on c.CategoryID equals p.CategoryID 4 into CategoryProducts 5 select new 6 { 7 c.CategoryName, 8 Products=CategoryProducts 9 }; 10 11 12 foreach (var item in productByCategoryResult) 13 { 14 Console.WriteLine("Category: {0}",item.CategoryName); 15 foreach(var product in item.Products) 16 { 17 Console.WriteLine("{0} ({1})", product.ProductName, product.Description); 18 } 19 }
如果要将子表达式的结果存储在变量中以便来执行其他操作,可以使用Let子句。例如这里需要统计分配给类别的产品数量。
1 var productByCategoryResult = from c in categories 2 join p in products 3 on c.CategoryID equals p.CategoryID 4 into CategoryProducts 5 let productCount=CategoryProducts.Count() 6 select new 7 { 8 c.CategoryName, 9 Count=productCount 10 }; 11 12 13 foreach (var item in productByCategoryResult) 14 { 15 Console.WriteLine("Category {0} have {1} products", item.CategoryName, item.Count); 16 }
好了,本篇就先到此,希望对你有所帮助,谢谢!