文章目录
前言
LINQ(语言集成查询)是 C# 中用于从数组、集合、数据库等数据源中进行查询和操作的强大功能。它提供了一种统一的方式来处理各种数据。
一、 LINQ 的基本概念
LINQ 是一种编程模式,可以让开发者以一种简洁的方式查询和操作数据。它简化了对数据的查询操作,使得数据操作变得更加直接和清晰。LINQ 可以与多种数据源结合使用,包括对象、数据库、XML 和数据集。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var query = from n in numbers
where n > 2
select n;
foreach (var num in query)
{
Console.WriteLine(num); // 输出: 3, 4, 5
}
}
}
二、查询语法与方法语法
LINQ 支持两种主要的语法:查询语法和方法语法。查询语法更接近于 SQL,适合用来执行复杂的查询;方法语法基于方法链,更加灵活。两者虽然不同,但可以实现同样的功能。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<string> names = new List<string> { "Alice", "Bob", "Charlie", "Dave" };
// 查询语法
var querySyntax = from name in names
where name.StartsWith("C")
select name;
// 方法语法
var methodSyntax = names.Where(n => n.StartsWith("C"));
Console.WriteLine("查询语法:");
foreach (var name in querySyntax) Console.WriteLine(name); // 输出: Charlie
Console.WriteLine("方法语法:");
foreach (var name in methodSyntax) Console.WriteLine(name); // 输出: Charlie
}
}
三、LINQ 的投影操作
投影操作允许开发者选择特定的数据字段。Select 方法可以用来实现投影操作,将数据转化为新的形态。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
static void Main()
{
List<Person> people = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Charlie", Age = 35 }
};
var names = people.Select(p => p.Name);
foreach (var name in names)
{
Console.WriteLine(name); // 输出: Alice, Bob, Charlie
}
}
}
四、LINQ 的排序操作
LINQ 允许按特定条件对数据进行排序,常用方法包括 OrderBy 和 OrderByDescending。这使得对结果进行排序变得非常简单。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
}
static void Main()
{
List<Product> products = new List<Product>
{
new Product { Name = "Laptop", Price = 999.99m },
new Product { Name = "Smartphone", Price = 499.99m },
new Product { Name = "Tablet", Price = 299.99m }
};
var sortedProducts = products.OrderBy(p => p.Price);
foreach (var product in sortedProducts)
{
Console.WriteLine($"{product.Name}: {product.Price}"); // 按价格输出产品
}
}
}
五、LINQ 的过滤操作
使用 Where 方法,开发者可以对数据进行筛选,只返回符合特定条件的元素。这是 LINQ 中最常用的操作之一。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var evenNumbers = numbers.Where(n => n % 2 == 0);
Console.WriteLine("偶数:");
foreach (var num in evenNumbers)
{
Console.WriteLine(num); // 输出: 2, 4, 6, 8, 10
}
}
}
六、LINQ 的分组操作
GroupBy 方法允许开发者按照某个属性将数据进行分组。通过分组,开发者可以更好地分析和展示数据。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Student
{
public string Name { get; set; }
public string Grade { get; set; }
}
static void Main()
{
List<Student> students = new List<Student>
{
new Student { Name = "Alice", Grade = "A" },
new Student { Name = "Bob", Grade = "B" },
new Student { Name = "Charlie", Grade = "A" },
new Student { Name = "David", Grade = "C" }
};
var groupedStudents = students.GroupBy(s => s.Grade);
foreach (var group in groupedStudents)
{
Console.WriteLine($"年级: {group.Key}");
foreach (var student in group)
{
Console.WriteLine($" - {student.Name}");
}
}
}
}
七、LINQ 的连接操作
通过 Join 方法,开发者可以将两个集合连接在一起,以便进行更复杂的数据查询和处理。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Enrollment
{
public int StudentId { get; set; }
public string Course { get; set; }
}
static void Main()
{
List<Student> students = new List<Student>
{
new Student { Id = 1, Name = "Alice" },
new Student { Id = 2, Name = "Bob" }
};
List<Enrollment> enrollments = new List<Enrollment>
{
new Enrollment { StudentId = 1, Course = "Math" },
new Enrollment { StudentId = 2, Course = "Science" },
new Enrollment { StudentId = 1, Course = "Science" }
};
var studentEnrollments = from student in students
join enrollment in enrollments on student.Id equals enrollment.StudentId
select new { student.Name, enrollment.Course };
foreach (var se in studentEnrollments)
{
Console.WriteLine($"{se.Name} 注册了 {se.Course}");
}
}
}
八、LINQ 的聚合操作
LINQ 提供多种聚合操作,这些操作允许开发者对数据进行总结和统计。例如,Count、Sum、Max 和 Average 方法可以帮助计算某些属性的总和或平均值。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int sum = numbers.Sum();
int count = numbers.Count();
int max = numbers.Max();
double average = numbers.Average();
Console.WriteLine($"总和: {sum}, 个数: {count}, 最大值: {max}, 平均值: {average}");
}
}
九、LINQ 的延迟执行
LINQ 查询默认情况下是延迟执行的,这意味着查询并不会在声明时执行,而是在实际迭代结果时才会被执行。这使得 LINQ 更加灵活,且在未被使用时不会消耗资源。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var query = numbers.Where(n => n > 2);
Console.WriteLine("查询尚未执行。");
foreach (var num in query)
{
Console.WriteLine(num); // 在此时查询会被执行
}
}
}
十、LINQ 的错误处理
编写 LINQ 查询时,可能会遇到异常。有效的错误处理机制是确保应用程序正常运行的关键。可以结合 try-catch 块来捕捉和处理这些异常。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = null; // 模拟空集合
try
{
var query = numbers.Where(n => n > 0);
foreach (var num in query)
{
Console.WriteLine(num);
}
}
catch (NullReferenceException ex)
{
Console.WriteLine("错误: " + ex.Message);
}
}
}
十一、LINQ 的合并操作
通过 Concat 和 Union 方法,LINQ 允许将多个集合连接在一起。Concat 不会移除重复项,而 Union 会移除重复项。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers1 = new List<int> { 1, 2, 3 };
List<int> numbers2 = new List<int> { 3, 4, 5 };
var concatenated = numbers1.Concat(numbers2);
var unioned = numbers1.Union(numbers2);
Console.WriteLine("连接结果:");
foreach (var num in concatenated)
{
Console.WriteLine(num); // 输出: 1, 2, 3, 3, 4, 5
}
Console.WriteLine("联合结果:");
foreach (var num in unioned)
{
Console.WriteLine(num); // 输出: 1, 2, 3, 4, 5
}
}
}
十二、LINQ 的自定义对象查询
LINQ 不只局限于内置的数据类型,也可以查询自定义对象。这为开发者提供了强大的数据操作能力。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
static void Main()
{
List<Book> books = new List<Book>
{
new Book { Title = "C# in Depth", Author = "Jon Skeet" },
new Book { Title = "Effective C#", Author = "Bill Wagner" },
new Book { Title = "CLR via C#", Author = "Jeffrey Richter" }
};
var query = from b in books
where b.Author.Contains("C#")
select b;
Console.WriteLine("包含 'C#' 的书籍:");
foreach (var book in query)
{
Console.WriteLine(book.Title);
}
}
}
十三、LINQ 的顺序查询
LINQ 支持按照多个字段进行排序,可以通过链式调用 OrderBy 和 ThenBy 方法实现。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class Employee
{
public string Name { get; set; }
public string Department { get; set; }
public decimal Salary { get; set; }
}
static void Main()
{
List<Employee> employees = new List<Employee>
{
new Employee { Name = "Alice", Department = "HR", Salary = 70000 },
new Employee { Name = "Bob", Department = "IT", Salary = 60000 },
new Employee { Name = "Charlie", Department = "HR", Salary = 80000 },
new Employee { Name = "David", Department = "IT", Salary = 90000 }
};
var sortedEmployees = employees.OrderBy(e => e.Department).ThenBy(e => e.Salary);
foreach (var emp in sortedEmployees)
{
Console.WriteLine($"{emp.Name} - {emp.Department} - {emp.Salary}");
}
}
}
十四、LINQ 的集合操作
LINQ 提供 Any、All、Contains 等方法,用于判断集合中的元素是否满足某个条件。这对于进行集合操作和条件检查非常有用。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
bool anyGreaterThan3 = numbers.Any(n => n > 3);
bool allGreaterThan0 = numbers.All(n => n > 0);
bool containsTwo = numbers.Contains(2);
Console.WriteLine($"有大于3的数: {anyGreaterThan3}");
Console.WriteLine($"所有数都大于0: {allGreaterThan0}");
Console.WriteLine($"包含2: {containsTwo}");
}
}
十五、LINQ 的数据聚集
LINQ 允许开发者轻松执行复杂的数据聚集操作,如 GroupBy 和 Aggregate 方法。特别是 Aggregate,可用于执行自定义的聚集操作。
示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int product = numbers.Aggregate((total, next) => total * next);
Console.WriteLine($"所有数的乘积: {product}"); // 输出: 120
}
}