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还是其他数据源,用法都一致

关键思想转变:

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

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

相关推荐
search71 天前
前端设计:CRG 3--CDC error
前端
治金的blog1 天前
vben-admin和vite,ant-design-vue的结合的联系
前端·vscode
利刃大大1 天前
【Vue】Vue2 和 Vue3 的区别
前端·javascript·vue.js
荔枝一杯酸牛奶1 天前
HTML 表单与表格布局实战:两个经典作业案例详解
前端·html
Charlie_lll1 天前
学习Three.js–纹理贴图(Texture)
前端·three.js
yuguo.im1 天前
我开源了一个 GrapesJS 插件
前端·javascript·开源·grapesjs
安且惜1 天前
带弹窗的页面--以表格形式展示
前端·javascript·vue.js
GISer_Jing1 天前
AI驱动营销:业务技术栈实战(From AIGC,待总结)
前端·人工智能·aigc·reactjs
GIS之路1 天前
GDAL 实现影像裁剪
前端·python·arcgis·信息可视化
AGMTI1 天前
webSock动态注册消息回调函数功能实现
开发语言·前端·javascript