LINQ 基础
LINQ
LINQ关键字
from 指定数据源和范围变量
where 根据布尔表达式(由逻辑与 或 等组成)从数据源中筛选元素
select 指定查询结果中的元素所具有的类型或表现形式
group 对对查询结果按照键值进行分组
into 提供一个标示符,它可以充当对 join group 或 select 子句结果的引用
orderby 对查询出的元素进行排序
join 按照两个指定匹配条件来联接俩个数据源
let 产生一个用于查询表达式中子表达式查询结果的范围变量
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication7LINQ { class Customer { public string ID { get; set; } public string City { get; set; } public string Country { get; set; } public string Region { get; set; } public decimal Sales { get; set; } public override string ToString()//重写ToString(),默认的ToString()仅输出类型名称 { return "ID:" + ID + "City:" + City + "Country:" + Country + "Region:" + Region + "Sales:" + Sales; } } class Order { public string ID { get; set; } public decimal Amount { get; set; } } class Program { /// <summary> /// 生成随机数组 /// </summary> /// <param name="count"></param> /// <returns></returns> private static int[] GenerateLotsofNumbers(int count) { Random generator = new Random(1); //使用指定的种子值初始化 Random 类的新实例。 int[] result = new int[count]; for (int i = 0; i < count; i++) { result[i] = generator.Next(); } return result; } //1.用var关键字声明结果变量 //2.指定数据源:from 子句 //3.指定条件:where 子句 //4.指定元素:select子句 //5.完成:使用foreach循环 static void Main(string[] args) { // string[] names = { "Alono", "Zheng", "Yuan", "Song", "Simle", "Hsieh", "Small", "She", "Sza", "Sam", "Fa", "Iyl" }; // //var queryResults = from n in names // // where n.StartsWith("S") // // orderby n descending//按照最后一个字母排序 ordeby n.Substring(n.Length - 1) // // select n;//查询语法 // var queryResults = names.OrderBy(n => n).Where(n => n.StartsWith("S"));//方法语法 Lambda 表达式 //// var queryResults = names.OrderByDescending(n => n).Where(n => n.StartsWith("S")); // foreach (var item in queryResults) // Console.WriteLine(item); // Console.ReadKey(); //-------------------------------------------------------------------------------------------------- //int[] numbers = GenerateLotsofNumbers(12345678); //var queryResults = from n in numbers // where n < 1000 // select n; //foreach (var item in queryResults) //{ // Console.WriteLine(item); //} //Console.WriteLine("聚合运算符......"); //Console.WriteLine(queryResults.Count()); //Console.WriteLine(queryResults .Max ()); //Console.WriteLine(queryResults.Average()); //Console.WriteLine(queryResults.Sum()); //Console.ReadKey(); //-------------------------------------------------------------------------------------------------- List<Customer> customers = new List<Customer> { new Customer {ID ="A",City ="New York",Country ="USA",Region ="North America",Sales =9999}, new Customer {ID ="B",City ="New York",Country ="USA",Region ="North America",Sales =9999}, new Customer {ID ="C",City ="XiAn",Country ="China",Region ="Asia",Sales =7777}, new Customer {ID ="D",City ="New York",Country ="USA",Region ="North America",Sales =9999}, new Customer {ID ="E",City ="BeiJing",Country ="China",Region ="Asia",Sales =8888}, new Customer {ID ="F",City ="New York",Country ="USA",Region ="North America",Sales =9999} }; //var queryReaults = // from n in customers // where n.Region == "Asia" // select n; //foreach (var item in queryReaults ) // Console.WriteLine(item); //Console.ReadKey(); //--------------------------------------投影---------------------------------------------- //投影是在LINQ查询中从其他数据类型中创建新数据类型的术语。 //var queryResults = // from c in customers // where c.Region == "Asia" // select new { c.City, c.Country, c.Sales }; //var queryResults = customers.Where(c => c.Region == "Asia").Select(c => new { c.City, c.Country, c.Sales }); //var queryResults = customers.Select(c => new { c.City, c.Country, c.Sales }).Where(c => c.City == "XiAn"); //foreach (var item in queryResults) // Console.WriteLine(item); //Console.ReadKey(); //--------------------单值选择查询------------------------ var queryResults1 = customers.Select(c => c.Region).Distinct(); var queryResults2 = (from c in customers select c.Region).Distinct(); //------------------------Any和All--------------------------------- bool anyUSA = customers.Any(c => c.Country == "USA"); if(anyUSA ) Console.WriteLine("some customers are in USA"); else Console.WriteLine("WAWA"); bool allAsia = customers.All(c => c.Region == "Asia"); if(allAsia ) Console.WriteLine("WAWA"); else Console.WriteLine("All customers are in Asia"); // Console.ReadKey(); //--------------------------------多级排序--------------------------------------- var queryReaults3 = from n in customers where n.Region == "Asia" orderby n.Region ,n.Country descending ,n.City //查询语法 多级排序 select n; var queryResults4 = customers.OrderBy(c => c.Region).ThenByDescending(c => c.Country).ThenBy(c => c.City).Select(c => new { c.ID, c.Region, c.Country, c.City }); //方法语法 多级排序 //------------------------------------组合查询(group query)------------------------------------- //组合查询中的数据通过一个键(Key)字段来组合,每一个组中的所有成员都共享这个字段值,在这个例子中 键字段是Region //要计算每个组的总和,应先生成一个新的结果集cg var queryResults5 = from c in customers group c by c.Region into cg select new { TotalSales = cg.Sum(c => c.Sales), Region = cg.Key }; var orderedResults = from cg in queryResults5 orderby cg.TotalSales descending select cg; foreach (var item in orderedResults) Console.WriteLine(item.TotalSales + "\t:" + item.Region); //Console.ReadKey(); //------------------------Take 和 Skip---------------------------------- //Take() 从查询结果中提取前n个结果 //Skip() 从查询结果中跳过前n个结果 返回剩余的结果 foreach (var item in orderedResults .Take (2)) Console.WriteLine(item.TotalSales + "\t:" + item.Region); //---------------------------First 和 FirstOrDefault------------------------------- //First() 返回结果集中第一个匹配给定条件的元素 //FirstOrDefault() 当查询条件不满足是,将为列表返回默认元素 而使用First()则返回null Console.WriteLine(queryReaults3.FirstOrDefault(n => n.Region == "Asia")); //--------------------------------集运算符----------------------------- List<Order> orders = new List<Order>{ new Order {ID="A",Amount=100}, new Order {ID ="B",Amount =200}, new Order {ID ="H",Amount =300}}; var customersIDs = from c in customers select c.ID; var ordersIDs = from o in orders select o.ID; var customersWithOrders = customersIDs.Intersect(ordersIDs);//Intersect() foreach (var item in customersWithOrders ) Console.WriteLine(item ); Console.WriteLine("-------------------------"); var ordersNoCustomers = ordersIDs.Except(customersIDs);//Except() foreach (var item in ordersNoCustomers ) Console.WriteLine(item ); Console.WriteLine("-------------------------"); var allCustomersOrders = ordersIDs.Union(customersIDs);//Union() foreach (var item in allCustomersOrders) Console.WriteLine(item); //Console.ReadKey(); //---------------------------------Join---------------------------- //使用Join运算符在一个查询中查找多个集合中的相关数据,用键字段把结果连接起来 var queryResults9 = from c in customers join o in orders on c.ID equals o.ID select new { c.ID, c.City, SalesBefore = c.Sales, NewOrder = o.Amount, SalesAfter = c.Sales + o.Amount }; foreach (var item in queryResults9 ) Console.WriteLine(item ); Console.ReadKey(); } } }
into子句
into子句作为一个临时标识符,用于group select join 子句中。它存储了into子句前面的查询内容,是后面的子句可以方便的使用,对其进行再次查询或排序 投影等操作。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 客户信息 /// </summary> public class GuestInfo { /// <summary> /// 姓名 /// </summary> public string Name { set; get; } /// <summary> /// 年龄 /// </summary> public int Age { set; get; } /// <summary> /// 电话 /// </summary> public string Tel { set; get; } /// <summary> /// 电话表 /// </summary> public List<string> TelTable { set; get; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace DemoInto { class Program { static void Main(string[] args) { //初始化集合 List<GuestInfo> gList = new List<GuestInfo>() { new GuestInfo { Name = "萧玉霜", Age = 17, Tel = "053*-985690**" }, new GuestInfo { Name = "萧玉若", Age = 21, Tel = "035*-120967**" }, new GuestInfo { Name = "徐长今", Age = 18, Tel = "039*-967512**" }, new GuestInfo { Name = "徐芷晴", Age = 24, Tel = "089*-569832**" } }; //按照名字的第一个字进行分组并用分组key进行排序 Console.WriteLine("into用于group子句的分组时刻"); var query = from guest in gList group guest by guest.Name.Substring(0, 1) into grguest orderby grguest.Key descending select grguest; //遍历分组数据 foreach (var guestGroup in query) { //输出当前分组的键值 Console.WriteLine(string.Format("分组键:{0} \n", guestGroup.Key)); //遍历组内元素 foreach (var g in guestGroup) Console.WriteLine(string.Format("{0} 电话:{1}", g.Name, g.Tel)); Console.WriteLine("\n**********************************\n"); } Console.WriteLine("\ninto用于select子句的投影时刻"); //select 子句中 的 info 子句使用 var query2 = from guest in gList select new{NewName = guest.Name, NewAge = guest.Age} into newguest orderby newguest.NewAge select newguest; //遍历分组数据 foreach (var g in query2) { Console.WriteLine(string.Format("{0} 年龄:{1}", g.NewName,g.NewAge)); } Console.ReadKey(); } } }
let子句
let语句在LINQ表达式中存储子表达式的计算结果。let子句创建一个范围变量来存储结果,变量被创建后,不能修改或把其他表达式的结果重新赋值给它。此范围变量可以在后续的LINQ语句中使用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace DemoLet { class Program { static void Main(string[] args) { //初始化集合 List<GuestInfo> gList = new List<GuestInfo>() { new GuestInfo { Name = "林晚荣", Age = 21, Tel = "026*-888888**" }, new GuestInfo { Name = "肖青漩", Age = 21, Tel = "017*-876543**" }, new GuestInfo { Name = "董巧巧", Age = 19, Tel = "029*-981256**" }, }; ///姓"肖"或姓 "董"的客户 var query = from guest in gList let g = guest.Name.Substring(0,1) where g == "肖" || g == "董" select guest; foreach (var g in query) Console.WriteLine(string.Format("{0} 年龄:{1} 电话:{2}", g.Name, g.Age, g.Tel)); Console.ReadKey(); } } }
join子句
如果一个数据源中元素的某一个属性可以跟另外一个数据源中元素的属性进行相等比较,那么着两个数据源可以用join子句进行关联
join子句使用equals关键字进行相等比较
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <summary> /// 客户职务 /// </summary> public class GuestTitle { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 职务 /// </summary> public string Tilte { get; set; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Program { static void Main(string[] args) { //初始化客户集合 List<GuestInfo> gList = new List<GuestInfo>() { new GuestInfo { Name = "林晚荣", Age = 21, Tel = "026*-888888**" }, new GuestInfo { Name = "肖青漩", Age = 21, Tel = "017*-876543**" }, new GuestInfo { Name = "董巧巧", Age = 19, Tel = "029*-981256**" }, new GuestInfo { Name = "徐芷晴", Age = 24, Tel = "089*-569832**" } }; ///初始化客户职务集合 List<GuestTitle> titleList = new List<GuestTitle>() { new GuestTitle{ Name = "林晚荣", Tilte = "金刀汉王"}, new GuestTitle{ Name = "林晚荣", Tilte = "天下第一丁"}, new GuestTitle{ Name = "肖青漩", Tilte = "出云公主"}, new GuestTitle{ Name = "董巧巧", Tilte = "酒店CEO"}, new GuestTitle{ Name = "董巧巧", Tilte = "乖巧人儿"} }; Console.WriteLine("内部联接"); //根据姓名进行内部联接 var query = from guest in gList join title in titleList on guest.Name equals title.Name select new { Name = guest.Name, Title = title.Tilte, Age = guest.Age }; foreach (var g in query) Console.WriteLine(string.Format("{0} {1} 年龄:{2}", g.Title, g.Name, g.Age)); Console.WriteLine("\n根据姓名进行分组联接"); //根据姓名进行分组联接 var query2 = from guest in gList join title in titleList on guest.Name equals title.Name into tgroup select new { Name = guest.Name, Titles = tgroup }; foreach (var g in query2) { Console.WriteLine(g.Name); foreach (var g2 in g.Titles) Console.WriteLine(string.Format(" {0}", g2.Tilte)); } Console.WriteLine("\n左外部联接"); //根据姓名进行左外部联接 var query3 = from guest in gList join title in titleList on guest.Name equals title.Name into tgroup from subtitle in tgroup.DefaultIfEmpty() select new { Name = guest.Name, Title = (subtitle == null ? "空缺" : subtitle.Tilte)} ; foreach (var g in query3) Console.WriteLine(string.Format("{0} {1}", g.Title, g.Name)); Console.ReadKey(); } }
注:以上代码来自《C#入门经典5》《LINQ入门及应用》!!!
posted on 2012-08-02 11:25 YuanSong 阅读(18371) 评论(1) 编辑 收藏 举报