C#,为什么要用LINQ?

想象你有一个杂乱的书架(数据集合)

不使用LINQ的情况(传统方式):

csharp

scss 复制代码
// 你有一堆书
List<Book> bookshelf = GetBookshelf();

// 你想找出所有计算机类的书,并按书名排序
List<Book> computerBooks = new List<Book>();

// 传统方式:像人工翻找每本书
foreach (var book in bookshelf)
{
    if (book.Category == "计算机")  // 逐一检查
    {
        computerBooks.Add(book);  // 手动收集
    }
}

// 然后再手动排序
computerBooks.Sort((a, b) => a.Title.CompareTo(b.Title));

使用LINQ的情况(智能助手帮你找书):

csharp

ini 复制代码
// 使用LINQ:像告诉智能助手你的需求
var computerBooks = bookshelf
    .Where(book => book.Category == "计算机")  // "只要计算机类的"
    .OrderBy(book => book.Title)                // "按书名排序"
    .ToList();                                  // "整理好给我"

LINQ的三种表达方式

1. 方法语法(最常用) - 像用手机App筛选外卖

csharp

ini 复制代码
var results = bookshelf
    .Where(b => b.Price < 50)      // 价格低于50元
    .OrderByDescending(b => b.Rating) // 按评分降序
    .Select(b => b.Title)          // 只要书名
    .Take(5);                     // 取前5本

2. 查询语法 - 像用自然语言提问

csharp

csharp 复制代码
var results = from book in bookshelf
              where book.Price < 50
              orderby book.Rating descending
              select book.Title
              take 5;
// 翻译:"从书架里,找价格低于50的书,按评分倒序排,只要书名,取前5个"

3. SQL风格 - 像数据库查询

csharp

less 复制代码
// LINQ to SQL / Entity Framework
var cheapBooks = from b in dbContext.Books
                 where b.Price < 30
                 select new { b.Title, b.Author };
// 这个会被翻译成SQL:SELECT Title, Author FROM Books WHERE Price < 30

现实生活场景对比

场景:整理家庭相册

csharp

ini 复制代码
// 你手机里有1000张照片
List<Photo> allPhotos = GetPhotosFromPhone();

// 需求1:找出去年拍的所有海滩照片,按时间排序
var beachPhotos = allPhotos
    .Where(p => p.Date.Year == 2023)
    .Where(p => p.Tags.Contains("海滩"))
    .OrderBy(p => p.Date);

// 需求2:统计每个月拍了多少张照片
var monthlyStats = allPhotos
    .GroupBy(p => p.Date.ToString("yyyy-MM"))
    .Select(g => new {
        Month = g.Key,
        Count = g.Count(),
        AvgSize = g.Average(p => p.FileSize)
    });

// 需求3:找出文件最大的10张照片
var largestPhotos = allPhotos
    .OrderByDescending(p => p.FileSize)
    .Take(10);

LINQ的核心优势

  1. 声明式编程:告诉计算机"要什么",而不是"怎么做"

    csharp

    arduino 复制代码
    // 传统:循环、判断、收集(关注过程)
    // LINQ:条件、排序、投影(关注结果)
  2. 延迟执行:像外卖下单,不马上做

    csharp

    csharp 复制代码
    var query = books.Where(b => b.Price > 100); // 只是"定义需求"
    
    // 真正需要数据时才执行(像下单后才开始做饭)
    foreach (var book in query)  // 这里才执行查询
    {
        Console.WriteLine(book.Title);
    }
  3. 可组合性:像搭积木

    csharp

    ini 复制代码
    var baseQuery = books.AsQueryable();
    
    // 根据不同条件组合查询
    if (userWantsCheapBooks)
        baseQuery = baseQuery.Where(b => b.Price < 50);
    
    if (userWantsByAuthor)
        baseQuery = baseQuery.Where(b => b.Author == "刘慈欣");
        
    // 最后才执行
    var results = baseQuery.ToList();

常见的LINQ操作(像厨房工具)

csharp

javascript 复制代码
// 1. 过滤(筛子):Where
books.Where(b => b.Rating > 4.0)

// 2. 映射(榨汁机):Select
books.Select(b => b.Title)  // 只要书名
books.Select(b => new { b.Title, b.Price }) // 提取部分信息

// 3. 排序(整理架):OrderBy/ThenBy
books.OrderBy(b => b.Price).ThenBy(b => b.Title)

// 4. 分组(分类盒):GroupBy
books.GroupBy(b => b.Category)  // 按类别分组

// 5. 聚合(计算器)
books.Count()                    // 总数
books.Average(b => b.Price)      // 平均价格
books.Sum(b => b.Pages)         // 总页数
books.Max(b => b.Price)         // 最贵的

// 6. 连接(拼图):Join(像合并两个清单)
var bookOrders = books.Join(orders,
    book => book.Id,           // 书的ID
    order => order.BookId,     // 订单中的书ID
    (book, order) => new { book.Title, order.Quantity });

实际代码示例:电商商品筛选

csharp

ini 复制代码
public class ProductService
{
    public List<Product> SearchProducts(
        decimal? maxPrice = null,
        string category = null,
        int minRating = 0,
        string sortBy = "price")
    {
        var query = _products.AsQueryable();
        
        // 动态构建查询条件
        if (maxPrice.HasValue)
            query = query.Where(p => p.Price <= maxPrice.Value);
        
        if (!string.IsNullOrEmpty(category))
            query = query.Where(p => p.Category == category);
            
        if (minRating > 0)
            query = query.Where(p => p.Rating >= minRating);
        
        // 动态排序
        query = sortBy switch
        {
            "price" => query.OrderBy(p => p.Price),
            "rating" => query.OrderByDescending(p => p.Rating),
            "sales" => query.OrderByDescending(p => p.MonthlySales),
            _ => query.OrderBy(p => p.Id)
        };
        
        return query.ToList();  // 一次性执行所有条件
    }
}

总结

LINQ就像你的数据管家:

  • 你不需要亲自翻箱倒柜找数据
  • 只需要告诉它你的需求(条件、排序、分组)
  • 它帮你高效地整理、筛选、计算
  • 无论是内存集合、数据库、XML还是其他数据源,用法都一致

关键思想转变:

从"我怎么一步步操作数据" → 到"我想要什么样的数据结果"

这就好比从"自己去仓库搬货、分类、贴标签"变成了"给仓储机器人一个需求清单,它帮你搞定一切"。

相关推荐
七宝三叔2 小时前
用「点外卖」的例子讲透HttpClient
前端
C_心欲无痕2 小时前
nodejs - pnpm解决幽灵依赖
前端·缓存·npm·node.js
二等饼干~za8986682 小时前
GEO优化---关键词搜索排名源码开发思路分享
大数据·前端·网络·数据库·django
韩曙亮2 小时前
【Web APIs】移动端轮播图案例 ( 轮播图自动播放 | 设置无缝衔接滑动 | 手指滑动轮播图 | 完整代码示例 )
前端·javascript·css·html·轮播图·移动端·web apis
犬大犬小2 小时前
Web 渗透:如何绕过403 Forbidden? Part I
前端·安全性测试·web 安全
AI前端老薛3 小时前
面试:了解闭包吗?
前端
xu_duo_i3 小时前
vue3+element-plus图片上传,前端压缩(纯函数,无插件)
前端·javascript·vue.js
林恒smileZAZ3 小时前
在 Web 前端实现流式 TTS 播放
前端
睡不着的可乐3 小时前
前端优化:requestAnimationFrame vs setInterval 性能对比与实战
前端