收集LINQ语法:

一、LINQ 的核心概念

  1. 什么是 LINQ?

    • 一种将查询能力直接集成到编程语言中的技术

    • 提供统一的语法查询多种数据源:

      • 内存对象集合(List,Array)

      • 数据库(SQL Server,Oracle)

      • XML 文档

      • JSON 数据

      • 实体数据模型

    • 编译时类型检查,避免运行时错误

  2. 核心组件

    =LINQ=

    LINQ to Objects

    LINQ to SQL

    LINQ to XML

    LINQ to Entities

    LINQ to DataSet

二、LINQ 的两种语法形式

1. 查询表达式语法(类似 SQL)

csharp

// 从集合中查询大于 10 的偶数,按降序排列 var result = from num in numbers where num > 10 && num % 2 == 0 orderby num descending select num * 2; // 将数值翻倍

2. 方法链语法(Lambda 表达式)

csharp

// 等效的链式方法调用
var result = numbers
    .Where(num => num > 10 && num % 2 == 0)
    .OrderByDescending(num => num)
    .Select(num => num * 2);

三、LINQ 的核心操作符

类别操作符功能描述示例
过滤Where条件过滤.Where(p => p.Price > 100)
投影Select / SelectMany选择/展平数据.Select(p => p.Name)
排序OrderBy / ThenBy升序排序.OrderBy(p => p.Price)
OrderByDescending降序排序.OrderByDescending(p => p.Price)
分组GroupBy数据分组.GroupBy(p => p.Category)
连接Join内连接.Join(.. on .. equals ..)
GroupJoin分组连接
聚合Count / Sum / Average计数/求和/平均值.Count().Sum(p => p.Price)
Min / Max最小值/最大值.Min(p => p.Age)
分区Take / Skip获取前N项/跳过前N项.Take(5).Skip(10)
TakeWhile / SkipWhile条件获取/跳过
集合Distinct去重.Distinct()
Union / Intersect并集/交集list1.Union(list2)
元素First / Last获取第一个/最后一个元素.First().Last()
FirstOrDefault安全获取第一个元素.FirstOrDefault()
转换ToArray / ToList转换为数组/列表.ToList()
ToDictionary转换为字典.ToDictionary(p => p.Id)
生成Range / Repeat生成数字序列/重复值序列Enumerable.Range(1, 10)

四、实际应用示例

示例 1:查询产品信息

csharp

复制

下载

class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; }
}

List<Product> products = new List<Product>
{
    new Product { ID = 1, Name = "笔记本电脑", Category = "电子", Price = 5999 },
    new Product { ID = 2, Name = "智能手机", Category = "电子", Price = 3999 },
    new Product { ID = 3, Name = "咖啡机", Category = "家电", Price = 899 }
};

// 查询所有电子类产品,按价格降序排列
var electronics = from p in products
                  where p.Category == "电子"
                  orderby p.Price descending
                  select new { 
                      p.Name, 
                      DiscountedPrice = p.Price * 0.9m // 打9折
                  };

// 等效方法语法
var electronicsMethod = products
    .Where(p => p.Category == "电子")
    .OrderByDescending(p => p.Price)
    .Select(p => new { 
        p.Name, 
        DiscountedPrice = p.Price * 0.9m
    });
示例 2:分组统计

csharp

复制

下载

// 按类别分组并计算每类产品的平均价格
var categoryStats = from p in products
                    group p by p.Category into g
                    select new {
                        Category = g.Key,
                        Count = g.Count(),
                        AvgPrice = g.Average(p => p.Price)
                    };

// 输出:电子类:2件产品,平均¥4999.00
foreach (var stat in categoryStats)
{
    Console.WriteLine($"{stat.Category}类:{stat.Count}件产品,平均{stat.AvgPrice:C}");
}

五、LINQ 的核心优势

  1. 声明式编程

    • 描述"要什么"而不是"如何获取"

    • 提高代码可读性

    csharp

    复制

    下载

    // 传统命令式
    List<string> results = new List<string>();
    foreach (var p in products)
    {
        if (p.Price > 1000)
            results.Add(p.Name.ToUpper());
    }
    
    // LINQ 声明式
    var results = products
        .Where(p => p.Price > 1000)
        .Select(p => p.Name.ToUpper());
  2. 统一查询模型

    • 相同的语法查询不同数据源

    • 降低学习曲线

  3. 延迟执行(Deferred Execution)

    • 查询定义时不立即执行

    • 实际使用时才执行(如遍历结果时)

    csharp

    复制

    下载

    var query = products.Where(p => p.Price > 1000); // 未执行
    
    // 添加新产品
    products.Add(new Product { Price = 2000 });
    
    foreach (var p in query) // 此时执行,包含新产品
    {
        Console.WriteLine(p.Name);
    }
  4. 强类型检查

    • 编译时检查查询语法

    • 避免运行时错误

六、LINQ 的实际应用场景

  1. 数据库访问(LINQ to SQL)

    csharp

    复制

    下载

    using (var db = new DataContext())
    {
        var customers = from c in db.Customers
                        where c.City == "北京"
                        orderby c.LastName
                        select c;
    }
  2. XML 处理(LINQ to XML)

    csharp

    复制

    下载

    XDocument doc = XDocument.Load("data.xml");
    var names = from element in doc.Descendants("Employee")
                where (int)element.Element("Age") > 30
                select element.Element("Name").Value;
  3. 内存集合处理

    csharp

    复制

    下载

    // 找出所有长度大于5的文件路径
    var longFiles = Directory.GetFiles("C:\\", "*", SearchOption.AllDirectories)
         .Where(file => new FileInfo(file).Length > 5 * 1024 * 1024)
         .OrderBy(file => file.Length);

七、性能注意事项

  1. 立即执行 vs 延迟执行

    • 使用 ToList()ToArray() 强制立即执行

    • 多次使用时缓存结果

  2. 复杂查询优化

    csharp

    复制

    下载

    // 低效:多次访问数据库
    for (int i = 0; i < ids.Length; i++)
    {
        var product = db.Products.First(p => p.ID == ids[i]);
    }
    
    // 高效:单次查询
    var products = db.Products.Where(p => ids.Contains(p.ID)).ToList();
  3. PLINQ(并行 LINQ)

    csharp

    复制

    下载

    // 自动并行处理大数据集
    var results = data.AsParallel()
                     .Where(item => ComplexCheck(item))
                     .ToList();

八、学习资源推荐

  1. 官方文档

  2. 交互式教程

  3. 经典书籍

    • 《C# in Depth》(Jon Skeet)

    • 《LINQ Pocket Reference》

LINQ 彻底改变了 .NET 开发者的数据处理方式,将查询能力提升为编程语言的一等公民。掌握 LINQ 不仅能提高开发效率,还能写出更简洁、更具表达力的代码。

namespace LINQ用法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 示例1:基本Select用法 - 创建匿名对象
            Console.WriteLine("===== 示例1:Select创建匿名对象 =====");

            // 创建简单整数列表
            List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

            // 使用Select和匿名对象创建新序列
            var squaredNumbers = numbers.Select(n => new
            {
                Original = n,          // 保留原始值
                Squared = n * n,       // 计算平方值
                IsEven = n % 2 == 0   // 判断是否为偶数
            });

            // 输出结果
            foreach (var item in squaredNumbers)
            {
                Console.WriteLine($"原始值: {item.Original}, " +
                                  $"平方: {item.Squared}, " +
                                  $"偶数? {item.IsEven}");
            }

            Console.WriteLine("\n");

            // 示例2:Zip和匿名对象组合数据
            Console.WriteLine("===== 示例2:Zip合并序列 =====");

            // 创建两个相关序列
            List<string> fruits = new List<string> { "苹果", "香蕉", "橙子" };
            List<double> prices = new List<double> { 5.99, 3.49, 4.25 };
            List<int> stock = new List<int> { 10, 15, 8 }; // 库存数量

            // 使用Zip合并水果和价格
            var fruitPricePairs = fruits.Zip(prices, (fruit, price) => new
            {
                FruitName = fruit,
                Price = price
            });

            Console.WriteLine("合并水果和价格:");
            foreach (var item in fruitPricePairs)
            {
                Console.WriteLine($"水果: {item.FruitName}, 价格: {item.Price:C}");
            }

            Console.WriteLine("\n");

            // 示例3:多层Zip嵌套(类似你的场景)
            Console.WriteLine("===== 示例3:多层Zip嵌套 =====");

            // 第一步:合并水果和价格
            var fruitPrice = fruits.Zip(prices, (f, p) => new
            {
                Name = f,
                Price = p
            });

            // 第二步:将上一步结果与库存合并
            var fullInfo = fruitPrice.Zip(stock, (fp, s) => new
            {
                Fruit = fp.Name,      // 从第一层对象获取水果名
                Price = fp.Price,     // 从第一层对象获取价格
                Stock = s             // 添加库存信息
            });

            Console.WriteLine("完整水果信息:");
            foreach (var item in fullInfo)
            {
                Console.WriteLine($"名称: {item.Fruit}, " +
                                  $"价格: {item.Price:C}, " +
                                  $"库存: {item.Stock}件");
            }

            Console.WriteLine("\n");

            // 示例4:链式调用(更紧凑的写法)
            Console.WriteLine("===== 示例4:链式调用 =====");

            var chainedResult = fruits
                .Zip(prices, (f, p) => new { Fruit = f, Price = p })
                .Zip(stock, (fp, s) => new
                {
                    Name = fp.Fruit,
                    Cost = fp.Price,
                    Inventory = s,
                    TotalValue = fp.Price * s // 计算总价值
                });

            Console.WriteLine("水果库存价值:");
            foreach (var item in chainedResult)
            {
                Console.WriteLine($"{item.Name}: " +
                                  $"单价 {item.Cost:C}, " +
                                  $"库存 {item.Inventory}, " +
                                  $"总值 {item.TotalValue:C}");
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值