LINQ 与查询
翻译整理自 LINQ 与 Standard query operators。
1. 查询语法 vs 方法语法
var nums = new[] { 1, 2, 3, 4, 5 };
// 查询语法
var evens = from x in nums
where x % 2 == 0
select x * x;
// 方法语法
var evens2 = nums
.Where(x => x % 2 == 0)
.Select(x => x * x);2. 常用运算符
nums.Where(x => x > 2);
nums.Select(x => x * 2);
nums.OrderBy(x => x);
nums.OrderByDescending(x => x);
nums.GroupBy(x => x % 2);
nums.Distinct();
nums.Take(3);
nums.Skip(2);
nums.First();
nums.FirstOrDefault();
nums.Any(x => x > 3);
nums.All(x => x > 0);
nums.Count();
nums.Sum();
nums.Average();
nums.Min(); nums.Max();
nums.Contains(3);
nums.Concat(other);
nums.Zip(other, (a, b) => a + b);
nums.Aggregate((a, b) => a + b);3. 投影与匿名类型
var result = users
.Select(u => new { u.Name, u.Age });
foreach (var r in result)
Console.WriteLine($"{r.Name} {r.Age}");4. 多源 join
var orders = users.Join(
items,
u => u.Id,
i => i.UserId,
(u, i) => new { u.Name, i.Name });
// 查询语法
var o = from u in users
join i in items on u.Id equals i.UserId
select new { u.Name, i.Name };5. GroupJoin
var groups = from u in users
join i in items on u.Id equals i.UserId into g
select new { u.Name, Items = g };6. 排序与分组
var sorted = nums.OrderBy(x => x).ThenByDescending(x => x);
var grouped = nums.GroupBy(x => x % 2)
.Select(g => new { Mod = g.Key, Sum = g.Sum() });7. ToList / ToDictionary
var list = nums.Where(x => x > 2).ToList();
var dict = users.ToDictionary(u => u.Id);
var set = users.ToHashSet();
var arr = nums.ToArray();8. 延迟执行
LINQ 查询默认惰性求值:
var q = nums.Where(x => x > 2);
nums.Add(10); // 修改源
foreach (var x in q) Console.WriteLine(x); // 包含 10强制立即求值:ToList、ToArray、Count 等。
9. Enumerable.Range 与 Repeat
var r = Enumerable.Range(1, 10);
var rep = Enumerable.Repeat("x", 5);10. LINQ to XML / JSON
using System.Xml.Linq;
var doc = XDocument.Parse("<root><item id='1'/></root>");
var ids = doc.Descendants("item")
.Select(e => (int)e.Attribute("id"));11. 表达式树与 IQueryable
IQueryable<T> 把 lambda 编译为表达式树,由 provider 翻译为目标查询(如 SQL):
// EF Core
var users = dbContext.Users
.Where(u => u.Age > 18)
.OrderBy(u => u.Name)
.ToList(); // 翻译为 SQL 执行12. PLINQ 并行
var r = nums.AsParallel()
.Where(x => x > 2)
.Select(x => x * 2);小结
LINQ 让查询、过滤、投影、分组像 SQL 一样优雅,是 C# 的杀手锏特性。