学习ORMX的查询构建功能,包括Where条件、OrderBy排序、GroupBy分组、Join连接和分页查询。 关键字:查询构建, Where条件, OrderBy排序, GroupBy分组, Join连接, 分页查询
第七章:查询构建
7.1 Where 条件查询
7.1.1 基本条件查询
使用 Where 方法添加查询条件:
using var userTable = tableManager.Table<User>();
// 查询年龄大于 25 的用户
var users = userTable.Where(u => u.Age > 25).GetList();
Console.WriteLine(<div class="latex">$"年龄大于 25 的用户:{users.Count} 个");
// 查询姓名为"张三"的用户
var user = userTable.Where(u => u.Name == "张三").FirstOrDefault();
支持的比较运算符:
==- 等于!=- 不等于>- 大于>=- 大于等于<- 小于<=- 小于等于
7.1.2 多条件查询
使用多个 Where 方法或使用逻辑运算符:
// 方法一:链式调用
var users = userTable
.Where(u => u.Age > 25)
.Where(u => u.Name == "张三")
.GetList();
// 方法二:逻辑运算符
var users = userTable.Where(u => u.Age > 25 && u.Name == "张三").GetList();
// 方法三:使用 || 运算符
var users = userTable.Where(u => u.Age > 25 || u.Name == "张三").GetList();
支持的逻辑运算符:
&&- 逻辑与(AND)||- 逻辑或(OR)!- 逻辑非(NOT)
7.1.3 Between 范围查询
使用 Between 方法查询指定范围内的数据:
// 查询年龄在 18 到 30 之间的用户
var users = userTable.Between(u => u.Age, 18, 30).GetList();
Console.WriteLine($</div>"年龄在 18-30 之间的用户:{users.Count} 个");
// 查询创建时间在指定日期范围内的用户
var users = userTable
.Between(u => u.CreatedAt, new DateTime(2023, 1, 1), new DateTime(2023, 12, 31))
.GetList();
7.1.4 NotBetween 排除范围查询
使用 NotBetween 方法查询指定范围外的数据:
// 查询年龄不在 18 到 30 之间的用户
var users = userTable.NotBetween(u => u.Age, 18, 30).GetList();
Console.WriteLine(<div class="latex">$"年龄不在 18-30 之间的用户:{users.Count} 个");
7.1.5 In 列表查询
使用 In 方法查询在指定列表中的数据:
// 查询 ID 为 1、2、3 的用户
var users = userTable.In(u => u.Id, 1, 2, 3).GetList();
Console.WriteLine($</div>"ID 为 1、2、3 的用户:{users.Count} 个");
// 查询姓名在指定列表中的用户
var names = new string[] { "张三", "李四", "王五" };
var users = userTable.In(u => u.Name, names).GetList();
7.1.6 NotIn 排除列表查询
使用 NotIn 方法查询不在指定列表中的数据:
// 查询 ID 不为 1、2、3 的用户
var users = userTable.NotIn(u => u.Id, 1, 2, 3).GetList();
Console.WriteLine(<div class="latex">$"ID 不为 1、2、3 的用户:{users.Count} 个");
7.1.7 Like 模糊查询
使用 Like 方法进行模糊查询:
// 查询姓名以"张"开头的用户
var users = userTable.Like(u => u.Name, "张%").GetList();
Console.WriteLine($</div>"姓名以张开头的用户:{users.Count} 个");
// 查询姓名包含"三"的用户
var users = userTable.Like(u => u.Name, "%三%").GetList();
Console.WriteLine(<div class="latex">$"姓名包含三的用户:{users.Count} 个");
// 查询姓名以"三"结尾的用户
var users = userTable.Like(u => u.Name, "%三").GetList();
Console.WriteLine($</div>"姓名以三结尾的用户:{users.Count} 个");
// 查询邮箱以"@example.com"结尾的用户
var users = userTable.Like(u => u.Email, "%@example.com").GetList();
通配符说明:
%- 匹配任意长度的任意字符_- 匹配单个任意字符
7.1.8 NotLike 排除模糊查询
使用 NotLike 方法排除模糊查询的结果:
// 查询姓名不以"张"开头的用户
var users = userTable.NotLike(u => u.Name, "张%").GetList();
Console.WriteLine(<div class="latex">$"姓名不以张开头的用户:{users.Count} 个");
7.1.9 组合高级条件
可以将高级条件与基本条件组合使用:
// 查询年龄在 18-30 之间且姓名以"张"开头的用户
var users = userTable
.Between(u => u.Age, 18, 30)
.Like(u => u.Name, "张%")
.GetList();
// 查询年龄在 18-30 之间且 ID 不为 1、2、3 的用户
var users = userTable
.Between(u => u.Age, 18, 30)
.NotIn(u => u.Id, 1, 2, 3)
.GetList();
// 查询姓名包含"三"且邮箱以"@example.com"结尾的用户
var users = userTable
.Like(u => u.Name, "%三%")
.Like(u => u.Email, "%@example.com")
.GetList();
7.1.10 字符串操作(Where 表达式)
除了使用 Like 方法外,还可以在 Where 表达式中使用字符串方法:
// LIKE 查询(包含)- 等价于 WHERE Name LIKE '%张%'
var users = userTable.Where(u => u.Name.Contains("张")).GetList();
// LIKE 查询(开头)- 等价于 WHERE Name LIKE '张%'
var users = userTable.Where(u => u.Name.StartsWith("张")).GetList();
// LIKE 查询(结尾)- 等价于 WHERE Name LIKE '%三'
var users = userTable.Where(u => u.Name.EndsWith("三")).GetList();
// 等于查询
var users = userTable.Where(u => u.Name == "张三").GetList();
// 不等于查询
var users = userTable.Where(u => u.Name != "张三").GetList();
7.1.11 WhereComplex 复杂条件组合
WhereComplex 方法允许在一个表达式中组合多个 Where 条件,支持复杂的逻辑运算(AND、OR、括号)。这对于构建复杂的查询条件非常有用。
7.1.11.1 基本用法
// 组合 Where 和 Where 条件
var users = userTable
.WhereComplex(w => w.Where(u => u.Id == 1) && w.Where(u => u.Name == "张三"))
.GetList();
// 生成 SQL: SELECT * FROM User WHERE ("Id" = @p1) AND ("Name" = @p0)
7.1.11.2 组合 Where 和高级条件
// 组合 Where 和 Between
var users = userTable
.WhereComplex(w => w.Where(u => u.Name == "张三") && w.Between(u => u.Age, 18, 30))
.GetList();
// 生成 SQL: SELECT * FROM User WHERE ("Name" = @p2) AND ("Age" BETWEEN @p0 AND @p1)
// 组合 Where 和 In
var users = userTable
.WhereComplex(w => w.Where(u => u.Name == "张三") && w.In(u => u.Id, 1, 2, 3))
.GetList();
// 生成 SQL: SELECT * FROM User WHERE ("Name" = @p3) AND ("Id" IN (@p0, @p1, @p2))
// 组合 Where 和 Like
var users = userTable
.WhereComplex(w => w.Where(u => u.Age > 18) && w.Like(u => u.Name, "张%"))
.GetList();
// 生成 SQL: SELECT * FROM User WHERE ("Age" > @p1) AND ("Name" LIKE @p0)
7.1.11.3 使用 OR 逻辑
// 使用 OR 逻辑
var users = userTable
.WhereComplex(w => w.Where(u => u.Id == 1) || w.Where(u => u.Id == 2))
.GetList();
// 生成 SQL: SELECT * FROM User WHERE "Id" = @p0 OR "Id" = @p1
7.1.11.4 复杂嵌套条件
// 复杂嵌套条件(使用括号)
var users = userTable
.WhereComplex(w =>
(w.Where(u => u.Name == "张三") && w.Between(u => u.Age, 18, 30)) ||
(w.Where(u => u.Name == "李四") && w.Between(u => u.Age, 25, 40))
)
.GetList();
// 生成 SQL: SELECT * FROM User WHERE
// (("Name" = @p4) AND ("Age" BETWEEN @p5 AND @p1)) OR
// (("Name" = @p0) AND ("Age" BETWEEN @p2 AND @p3))
7.1.11.5 多条件组合
// 多个条件的复杂组合
var users = userTable
.WhereComplex(w =>
(w.Where(u => u.Name == "张三") && w.Between(u => u.Age, 18, 30) && w.In(u => u.Id, 1, 2, 3)) ||
(w.Where(u => u.Name == "李四") && w.NotBetween(u => u.Age, 40, 60) && w.Like(u => u.Email, "%company.com")) ||
(w.Where(u => u.Age > 18) && w.NotIn(u => u.Id, 10, 11, 12) && w.NotLike(u => u.Name, "Test%"))
)
.GetList();
WhereComplex 的优势:
- 支持复杂的逻辑运算(AND、OR、括号)
- 可以在一个表达式中组合多个 Where 条件
- 生成的 SQL 更清晰,可读性更好
- 适合构建复杂的查询条件
7.1.12 多表连接
ORMX 支持 JOIN 操作,可以连接多个表进行查询。关于 JOIN 操作的详细用法,请参考连表查询。
// 内连接
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
// 左连接
var result = userTable
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
// 右连接
var result = userTable
.RightJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
// 全连接
var result = userTable
.FullJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
关于 JOIN 操作的详细说明,请查阅连表查询。
7.2 OrderBy 排序
7.2.1 单字段排序
// 升序排序
var users = userTable.OrderBy(u => u.Age).GetList();
// 降序排序
var users = userTable.OrderByDesc(u => u.Age).GetList();
7.2.2 多字段排序
// 先按年龄升序,再按姓名降序
var users = userTable
.OrderBy(u => u.Age)
.OrderByDesc(u => u.Name)
.GetList();
7.2.3 多表排序
在 Join 查询中排序:
var result = userTable
.Join<Order, User, Order, object>(
(u, o) => u.Id == o.UserId,
(u, o) => new { u.Name, o.Amount }
)
.OrderBy(x => x.Name)
.GetList();
7.3 GroupBy 分组
7.3.1 单字段分组
// 按年龄分组
var groups = userTable
.GroupBy(u => u.Age)
.Max(u => u.Age, "MaxAge")
.Min(u => u.Age, "MinAge")
.Count(u => u.Id, "Count")
.GetList<AgeGroupStats>();
7.3.2 多字段分组
// 按年龄和姓名分组
var groups = userTable
.GroupBy(u => new { u.Age, u.Name })
.Max(u => u.Age, "MaxAge")
.Count(u => u.Id, "Count")
.GetList<AgeNameGroupStats>();
关于聚合函数的详细用法,请查阅聚合函数。
7.4 Having 分组后筛选
// 分组后筛选数量大于 1 的组
var groups = userTable
.GroupBy(u => u.Age)
.Having(u => u.Age > 25)
.Max(u => u.Age, "MaxAge")
.Count(u => u.Id, "Count")
.GetList<AgeGroupStats>();
7.5 Join 连接查询
ORMX 支持多种 JOIN 操作,包括 INNER JOIN、LEFT JOIN、RIGHT JOIN 和 FULL JOIN。关于 JOIN 操作的详细说明,请查阅连表查询。
7.5.1 内连接(INNER JOIN)
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
7.5.2 左连接(LEFT JOIN)
var result = userTable
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
7.5.3 右连接(RIGHT JOIN)
var result = userTable
.RightJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
7.5.4 全连接(FULL JOIN)
var result = userTable
.FullJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
7.5.5 无限级联 Join
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.InnerJoin<Product>((o, p) => o.Id == p.OrderId)
.GetList();
关于 JOIN 操作的详细说明,请查阅连表查询。
7.6 Select 选择列
7.6.1 选择单个列
// 选择姓名列
var names = userTable.Select(u => u.Name).GetList();
7.6.2 选择多个列
// 选择姓名和邮箱列
var users = userTable.Select(u => new { u.Name, u.Email }).GetList();
7.7 Limit/Offset 分页
7.7.1 Limit 限制结果数量
// 只返回前 10 条记录
var users = userTable.Limit(10).GetList();
7.7.2 Offset 跳过记录
// 跳过前 10 条记录,返回剩余记录
var users = userTable.Offset(10).GetList();
7.7.3 分页查询
// 每页 10 条,获取第 2 页
var pageSize = 10;
var pageNumber = 2;
var users = userTable
.Offset((pageNumber - 1) * pageSize)
.Limit(pageSize)
.GetList();
7.8 链式查询组合
ORMX 支持链式调用,可以组合多个查询方法:
var users = userTable
.Where(u => u.Age > 25)
.Where(u => u.Name.Contains("张"))
.OrderByDesc(u => u.Age)
.Limit(10)
.GetList();
7.9 查询执行
7.9.1 GetList
将查询结果转换为列表:
var users = userTable.Where(u => u.Age > 25).GetList();
7.9.2 FirstOrDefault
返回第一个元素,如果没有则返回 null:
var user = userTable.Where(u => u.Name == "张三").FirstOrDefault();
7.9.3 GetOne
返回单个元素,如果没有则返回 null:
var user = userTable.Where(u => u.Id == 1).GetOne();
7.10 完整示例
using System;
using JCode.ORMX.Attributes;
using JCode.ORMX.DbProvider;
using JCode.ORMX.Core;
using Microsoft.Data.Sqlite;
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
// 创建数据库提供程序(推荐方式)
using var provider = new SqliteDatabaseProvider("Data Source=:memory:");
var tableManager = provider.GetTableManager();
var userTable = tableManager.Table<User>();
// 1. 条件查询
Console.WriteLine("=== 条件查询 ===");
var users = userTable
.Where(u => u.Age > 25)
.GetList();
Console.WriteLine($</div>"年龄大于 25 的用户:{users.Count} 个");
// 2. 排序查询
Console.WriteLine("\n=== 排序查询 ===");
var sortedUsers = userTable
.OrderByDesc(u => u.Age)
.GetList();
foreach (var user in sortedUsers)
{
Console.WriteLine(<div class="latex">$"姓名: {user.Name}, 年龄: {user.Age}");
}
// 3. 分页查询
Console.WriteLine("\n=== 分页查询 ===");
var pagedUsers = userTable
.Offset(0)
.Limit(2)
.GetList();
Console.WriteLine($</div>"前 2 个用户:{pagedUsers.Count} 个");
}
}
总结
本章介绍了 ORMX 框架的查询构建功能,包括 Where 条件查询、OrderBy 排序、GroupBy 分组、Join 连接和分页查询。ORMX 提供了丰富的查询方法,支持链式调用,可以灵活组合各种查询条件。WhereComplex 方法允许构建复杂的逻辑条件,支持 AND、OR 和括号运算。合理使用查询构建功能,可以高效地检索和过滤数据。
扩展思考
在复杂查询场景下,如何优化查询性能?是否需要使用索引、查询计划分析等技术?对于大数据量的查询,如何避免内存溢出和性能问题?在分布式系统中,如何实现跨节点的查询和聚合?这些问题值得在深入使用 ORMX 后进一步思考。