1. LINQ(Language - Integrated Query)概述
- LINQ是一种在C#(和VB.NET)中用于查询数据的统一语法,它能够对各种数据源(如对象集合、数据库、XML等)进行查询操作。它将查询功能直接集成到了C#语言中,使得查询操作更加方便、简洁和易于理解。
- LINQ提供了一组标准的查询操作符,这些操作符可以用于筛选、排序、分组、连接等常见的查询操作,就像在SQL中对数据库进行查询一样,但它的应用范围更广泛。
2. LINQ的基本使用步骤
- 引入命名空间
- 对于大多数LINQ to Objects(查询对象集合)的情况,需要引入
System.Linq
命名空间。如果是LINQ to SQL或其他特定数据源的LINQ,可能还需要引入相关的数据库访问命名空间等。 - 例如:
using System.Linq;
- 对于大多数LINQ to Objects(查询对象集合)的情况,需要引入
- 定义数据源
- LINQ可以对各种数据源进行操作,最常见的是对象集合。例如,定义一个简单的整数集合作为数据源:
int[] numbers = { 1, 2, 3, 4, 5 };
- LINQ可以对各种数据源进行操作,最常见的是对象集合。例如,定义一个简单的整数集合作为数据源:
- 编写LINQ查询表达式
- LINQ查询表达式类似于SQL查询语句的语法。例如,要筛选出大于3的数字,可以这样写:
var result = from n in numbers where n > 3 select n;
- 这个查询表达式的意思是:从
numbers
集合中的每个元素n
开始,筛选出满足n > 3
条件的元素,然后选择这些元素作为结果。查询结果result
是一个IEnumerable<int>
类型的集合。
- LINQ查询表达式类似于SQL查询语句的语法。例如,要筛选出大于3的数字,可以这样写:
- 执行查询并处理结果
- LINQ查询采用延迟执行机制,即查询表达式在定义时并不会立即执行,而是在遍历查询结果(例如使用
foreach
循环)或者调用某些会强制立即执行的方法(如ToList
、ToArray
等)时才执行。 - 例如,使用
foreach
循环来处理查询结果:foreach (var number in result) { Console.WriteLine(number); }
- 或者将结果转换为列表后处理:
var resultList = result.ToList(); // 可以对resultList进行其他操作,如添加、删除元素等
- LINQ查询采用延迟执行机制,即查询表达式在定义时并不会立即执行,而是在遍历查询结果(例如使用
3. LINQ查询操作符
- 筛选操作符(Where)
- 用于从数据源中筛选出符合特定条件的元素。例如,对于一个包含学生对象的集合,筛选出成绩大于80分的学生:
class Student { public string Name { get; set; } public int Score { get; set; } } Student[] students = { new Student { Name = "Alice", Score = 85 }, new Student { Name = "Bob", Score = 78 }, new Student { Name = "Charlie", Score = 90 } }; var highScoreStudents = from s in students where s.Score > 80 select s;
- 用于从数据源中筛选出符合特定条件的元素。例如,对于一个包含学生对象的集合,筛选出成绩大于80分的学生:
- 排序操作符(OrderBy和OrderByDescending)
OrderBy
用于按照指定的属性升序排序,OrderByDescending
用于降序排序。例如,对学生按成绩升序排序:var sortedStudents = from s in students OrderBy s.Score select s;
- 分组操作符(GroupBy)
- 用于将数据源中的元素按照指定的键进行分组。例如,将学生按成绩区间进行分组:
var groupedStudents = from s in students group s by s.Score >= 80? "High Score" : "Low Score"; foreach (var group in groupedStudents) { Console.WriteLine(group.Key); foreach (var student in group) { Console.WriteLine(" " + student.Name); } }
- 用于将数据源中的元素按照指定的键进行分组。例如,将学生按成绩区间进行分组:
- 投影操作符(Select)
- 用于从数据源中选择需要的属性或进行一些计算后返回新的结果。例如,只选择学生的姓名:
var studentNames = from s in students select s.Name;
- 或者进行一些计算,如计算每个学生成绩的平方:
var scoreSquares = from s in students select s.Score * s.Score;
- 用于从数据源中选择需要的属性或进行一些计算后返回新的结果。例如,只选择学生的姓名:
- 连接操作符(Join)
- 类似于SQL中的JOIN操作,用于将两个数据源根据指定的键进行连接。例如,假设有两个集合,一个是学生集合,一个是课程集合,要找出每个学生所选的课程:
class Course { public string CourseName { get; set; } public int StudentId { get; set; } } Student[] students = { new Student { Name = "Alice", StudentId = 1 }, new Student { Name = "Bob", StudentId = 2 } }; Course[] courses = { new Course { CourseName = "Math", StudentId = 1 }, new Course { CourseName = "English", StudentId = 1 }, new Course { CourseName = "Science", StudentId = 2 } }; var studentCourses = from s in students join c in courses on s.StudentId equals c.StudentId select new { s.Name, c.CourseName };
- 类似于SQL中的JOIN操作,用于将两个数据源根据指定的键进行连接。例如,假设有两个集合,一个是学生集合,一个是课程集合,要找出每个学生所选的课程:
4. LINQ的不同实现方式
- 查询表达式语法
- 这是前面介绍的类似于SQL的语法,它的优点是直观、易于理解,对于熟悉SQL的开发人员来说很容易上手。例如:
var query = from p in products where p.Price < 100 select p;
- 这是前面介绍的类似于SQL的语法,它的优点是直观、易于理解,对于熟悉SQL的开发人员来说很容易上手。例如:
- 方法语法
- LINQ查询也可以使用方法链的形式来表达。上面的查询用方法语法可以写成:
var query = products.Where(p => p.Price < 100).Select(p => p);
- 方法语法更灵活,在一些复杂的查询场景下可能更方便,特别是当查询需要调用自定义方法或者使用更复杂的Lambda表达式时。
- LINQ查询也可以使用方法链的形式来表达。上面的查询用方法语法可以写成:
- LINQ to SQL、LINQ to XML等特定领域的LINQ
- LINQ to SQL用于查询关系型数据库,它允许开发人员使用LINQ语法来编写数据库查询,而不是传统的SQL语句。通过将数据库表映射到C#对象,然后使用LINQ查询这些对象来间接查询数据库。
- LINQ to XML用于查询和操作XML数据,它提供了一种方便的方式来遍历XML元素、属性等,并且可以使用LINQ查询来筛选、转换XML数据。例如,查询一个XML文档中的所有元素节点:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Element1>Value1</Element1> <Element2>Value2</Element2> </Root>
XDocument xmlDoc = XDocument.Load("example.xml"); var elements = from e in xmlDoc.Descendants() select e;