LINQ 查询数据库

LINQ(Language Integrated Query)与数据库的结合主要通过 LINQ to SQLEntity Framework 来实现。这两种技术允许开发者使用 LINQ 查询数据库中的数据,类似于查询内存中的对象。这里以 Entity Framework(EF)为主要示例,因为它是目前最流行的 ORM(对象关系映射)工具之一,并广泛支持 LINQ 查询数据库。

一、什么是 Entity Framework(EF)

Entity Framework 是微软提供的一个对象关系映射(ORM)框架,允许开发者使用面向对象的方式与数据库交互。EF 可以将数据库中的表映射为 C# 对象,并使用 LINQ 查询这些对象来执行数据库操作。

EF 有两种常用的模型构建方式:

  1. Code First:使用代码定义数据模型,数据库根据代码自动生成。
  2. Database First:从现有数据库生成数据模型,适用于已有数据库的场景。

二、使用 LINQ 查询数据库的基本步骤

1. 准备工作

首先,确保已经安装并配置了 Entity Framework。可以通过 NuGet 安装 Entity Framework 包。

Install-Package EntityFramework

创建一个数据模型。假设我们有一个名为 Customer 的表,其结构如下:

IdNameCity
1AliceNew York
2BobLos Angeles
3CharlieNew York
2. 创建数据模型

使用 Code First 方式创建数据模型。首先定义实体类和上下文类:

// Customer.cs
public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string City { get; set; }
}

// AppDbContext.cs
using System.Data.Entity;

public class AppDbContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}
3. 生成数据库

Code First 模式下,可以通过 EF 自动生成数据库。

using (var context = new AppDbContext())
{
    if (!context.Customers.Any())
    {
        context.Customers.Add(new Customer { Name = "Alice", City = "New York" });
        context.Customers.Add(new Customer { Name = "Bob", City = "Los Angeles" });
        context.Customers.Add(new Customer { Name = "Charlie", City = "New York" });
        context.SaveChanges();
    }
}

三、使用 LINQ 查询数据库

1. 简单查询

使用 LINQ 查询数据库中的数据,获取所有客户信息。

using (var context = new AppDbContext())
{
    var customers = from c in context.Customers
                    select c;

    foreach (var customer in customers)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}

上述查询使用了 LINQ 的查询语法,也可以使用方法语法来完成相同的操作:

using (var context = new AppDbContext())
{
    var customers = context.Customers.ToList();

    foreach (var customer in customers)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}
2. 带条件的查询

使用 Where 过滤数据,查询所有在 “New York” 城市的客户。

using (var context = new AppDbContext())
{
    var customersInNewYork = from c in context.Customers
                             where c.City == "New York"
                             select c;

    foreach (var customer in customersInNewYork)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}

方法语法实现相同的操作:

using (var context = new AppDbContext())
{
    var customersInNewYork = context.Customers
                                     .Where(c => c.City == "New York")
                                     .ToList();

    foreach (var customer in customersInNewYork)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}
3. 投影查询

使用 Select 操作符,只选择客户的名字。

using (var context = new AppDbContext())
{
    var customerNames = from c in context.Customers
                        select c.Name;

    foreach (var name in customerNames)
    {
        Console.WriteLine(name);
    }
}

方法语法的实现方式:

using (var context = new AppDbContext())
{
    var customerNames = context.Customers
                               .Select(c => c.Name)
                               .ToList();

    foreach (var name in customerNames)
    {
        Console.WriteLine(name);
    }
}
4. 排序查询

可以使用 OrderByOrderByDescending 对数据进行排序。下面的例子按客户名字进行升序排序:

using (var context = new AppDbContext())
{
    var sortedCustomers = from c in context.Customers
                          orderby c.Name
                          select c;

    foreach (var customer in sortedCustomers)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}

方法语法实现:

using (var context = new AppDbContext())
{
    var sortedCustomers = context.Customers
                                 .OrderBy(c => c.Name)
                                 .ToList();

    foreach (var customer in sortedCustomers)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}
5. 分组查询

使用 GroupBy 根据某个字段分组,比如按城市分组客户。

using (var context = new AppDbContext())
{
    var groupedCustomers = from c in context.Customers
                           group c by c.City into cityGroup
                           select cityGroup;

    foreach (var group in groupedCustomers)
    {
        Console.WriteLine($"City: {group.Key}");
        foreach (var customer in group)
        {
            Console.WriteLine($"  {customer.Name}");
        }
    }
}

方法语法的实现方式:

using (var context = new AppDbContext())
{
    var groupedCustomers = context.Customers
                                  .GroupBy(c => c.City)
                                  .ToList();

    foreach (var group in groupedCustomers)
    {
        Console.WriteLine($"City: {group.Key}");
        foreach (var customer in group)
        {
            Console.WriteLine($"  {customer.Name}");
        }
    }
}
6. 连接查询

可以使用 Join 连接两个不同的表。假设我们有另一个表 Order,表示客户的订单。

public class Order
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public string Product { get; set; }
    public int Quantity { get; set; }
}

查询所有客户及其订单信息:

using (var context = new AppDbContext())
{
    var query = from c in context.Customers
                join o in context.Orders on c.Id equals o.CustomerId
                select new { c.Name, o.Product, o.Quantity };

    foreach (var result in query)
    {
        Console.WriteLine($"{result.Name} ordered {result.Quantity} of {result.Product}");
    }
}

四、执行 SQL 查询

除了使用 LINQ 查询数据,Entity Framework 还支持直接执行原生 SQL 查询:

using (var context = new AppDbContext())
{
    var customers = context.Database.SqlQuery<Customer>("SELECT * FROM Customers WHERE City = 'New York'").ToList();

    foreach (var customer in customers)
    {
        Console.WriteLine($"{customer.Name} - {customer.City}");
    }
}

五、延迟执行与立即执行

LINQ 查询的特点之一是延迟执行,即查询不会在定义时执行,而是在遍历或调用方法(如 ToList()Count() 等)时执行。这有助于提高查询性能。

var query = context.Customers.Where(c => c.City == "New York"); // 查询未执行

var resultList = query.ToList(); // 查询在此时执行

六、总结

  1. LINQ 提供了一个统一的数据查询语法,可以用来查询数据库、内存集合、XML 等数据源。
  2. Entity Framework 结合 LINQ 提供了强大的 ORM 功能,简化了数据库操作。
  3. 查询表达式和方法语法各有特点,可以混合使用。
  4. 延迟执行有助于提高性能,但需要注意可能的副作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好玩的Matlab(NCEPU)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值