SqlSugar 动态表达式查询功能解析与实战应用

SqlSugar 动态表达式查询功能解析与实战应用

【免费下载链接】SqlSugar DotNetNext/SqlSugar: 这是一个用于SQL Server和MySQL的ORM框架。适合用于需要简化数据库操作的场景。特点:易于使用,支持多种数据库,具有代码生成和自动映射功能。 【免费下载链接】SqlSugar 项目地址: https://gitcode.com/DotNetNext/SqlSugar

引言:告别硬编码查询的束缚

在日常开发中,你是否经常遇到这样的场景:需要根据用户输入动态构建查询条件,但传统的LINQ表达式无法满足灵活多变的业务需求?或者面对复杂的多条件组合查询时,代码变得冗长且难以维护?

SqlSugar的**动态表达式查询(Dynamic Expression Query)**功能正是为解决这些痛点而生。它提供了强大的表达式构建能力,让你能够以编程方式动态生成查询条件,彻底告别硬编码的束缚。

动态表达式核心组件解析

Expressionable :表达式构建利器

SqlSugar通过Expressionable<T>类提供动态表达式构建能力,支持1-12个泛型参数的表达式组合:

public class Expressionable<T> where T : class, new()
{
    Expression<Func<T, bool>> _exp = null;

    // 添加AND条件
    public Expressionable<T> And(Expression<Func<T, bool>> exp)
    {
        if (_exp == null)
            _exp = exp;
        else
            _exp = Expression.Lambda<Func<T, bool>>(
                Expression.AndAlso(_exp.Body, exp.Body), _exp.Parameters);
        return this;
    }

    // 条件性添加AND
    public Expressionable<T> AndIF(bool isAnd, Expression<Func<T, bool>> exp)
    {
        if (isAnd) And(exp);
        return this;
    }

    // 添加OR条件
    public Expressionable<T> Or(Expression<Func<T, bool>> exp)
    {
        if (_exp == null)
            _exp = exp;
        else
            _exp = Expression.Lambda<Func<T, bool>>(
                Expression.OrElse(_exp.Body, exp.Body), _exp.Parameters);
        return this;
    }

    // 条件性添加OR
    public Expressionable<T> OrIF(bool isOr, Expression<Func<T, bool>> exp)
    {
        if (isOr) Or(exp);
        return this;
    }

    // 转换为表达式
    public Expression<Func<T, bool>> ToExpression()
    {
        return _exp ?? (it => true);
    }
}

多表关联表达式支持

SqlSugar还提供了多表关联的表达式构建器:

// 双表表达式构建器
public class Expressionable<T, T2> where T : class, new() where T2 : class, new()
{
    // 支持AND/OR操作,与单表类似
}

// 三表表达式构建器  
public class Expressionable<T, T2, T3> where T : class, new() where T2 : class, new() where T3 : class, new()
{
    // 支持AND/OR操作
}

实战应用场景

场景1:动态多条件搜索

// 用户搜索条件
var searchModel = new UserSearchModel 
{
    Name = "张三",
    Age = 25,
    Department = "技术部"
};

// 动态构建查询表达式
var exp = Expressionable.Create<User>()
    .AndIF(!string.IsNullOrEmpty(searchModel.Name), u => u.Name.Contains(searchModel.Name))
    .AndIF(searchModel.Age > 0, u => u.Age == searchModel.Age)
    .AndIF(!string.IsNullOrEmpty(searchModel.Department), u => u.Department == searchModel.Department);

var users = db.Queryable<User>().Where(exp.ToExpression()).ToList();

场景2:复杂条件组合查询

// 构建复杂的OR条件组合
var keywords = new string[] { "紧急", "重要", "高优先级" };
var exp = Expressionable.Create<Task>();

foreach (var keyword in keywords)
{
    exp.Or(t => t.Title.Contains(keyword) || t.Description.Contains(keyword));
}

// 添加额外的AND条件
exp.And(t => t.Status == TaskStatus.Active)
   .And(t => t.DueDate >= DateTime.Today);

var tasks = db.Queryable<Task>().Where(exp.ToExpression()).ToList();

场景3:多表关联动态查询

// 用户和部门的关联查询
var exp = Expressionable.Create<User, Department>()
    .AndIF(!string.IsNullOrEmpty(userName), (u, d) => u.Name.Contains(userName))
    .AndIF(departmentId > 0, (u, d) => u.DepartmentId == departmentId)
    .AndIF(!string.IsNullOrEmpty(departmentName), (u, d) => d.Name.Contains(departmentName));

var result = db.Queryable<User, Department>((u, d) => u.DepartmentId == d.Id)
              .Where(exp.ToExpression())
              .Select((u, d) => new UserDto 
              { 
                  UserName = u.Name, 
                  DepartmentName = d.Name 
              })
              .ToList();

高级特性深度解析

WhereIF条件方法

SqlSugar提供了内置的WhereIF方法,简化条件查询:

var query = db.Queryable<User>()
    .WhereIF(!string.IsNullOrEmpty(name), u => u.Name.Contains(name))
    .WhereIF(age > 0, u => u.Age == age)
    .WhereIF(departmentId > 0, u => u.DepartmentId == departmentId)
    .ToList();

表达式性能优化

mermaid

表达式组合模式

// 模块化表达式构建
public Expression<Func<User, bool>> BuildNameFilter(string name)
{
    return u => u.Name.Contains(name);
}

public Expression<Func<User, bool>> BuildAgeFilter(int? minAge, int? maxAge)
{
    var exp = Expressionable.Create<User>();
    if (minAge.HasValue) exp.And(u => u.Age >= minAge.Value);
    if (maxAge.HasValue) exp.And(u => u.Age <= maxAge.Value);
    return exp.ToExpression();
}

// 组合使用
var finalExp = Expressionable.Create<User>()
    .And(BuildNameFilter("张"))
    .And(BuildAgeFilter(20, 30))
    .ToExpression();

最佳实践与性能考量

实践1:表达式缓存策略

// 使用静态字段缓存常用表达式
private static readonly Expression<Func<User, bool>> ActiveUsersExpression = 
    u => u.IsActive && u.Status == UserStatus.Normal;

// 使用时组合
var exp = Expressionable.Create<User>()
    .And(ActiveUsersExpression)
    .AndIF(condition, u => u.Age > 18)
    .ToExpression();

实践2:避免表达式过度复杂化

// 不推荐:过于复杂的单表达式
var badExp = u => (u.Name.Contains("A") || u.Name.Contains("B")) && 
                 (u.Age > 20 || u.Age < 30) && 
                 (u.Department == "IT" || u.Department == "HR");

// 推荐:分步构建,清晰易维护
var goodExp = Expressionable.Create<User>()
    .And(u => u.Name.Contains("A") || u.Name.Contains("B"))
    .And(u => u.Age > 20 || u.Age < 30)
    .And(u => u.Department == "IT" || u.Department == "HR")
    .ToExpression();

性能对比表格

查询方式执行时间内存占用可维护性适用场景
硬编码LINQ⚡️ 最快🟢 最低🔴 差固定条件查询
Expressionable🟡 中等🟡 中等🟢 优秀动态条件查询
字符串SQL🔴 最慢🔴 最高🟡 一般极端复杂查询

常见问题与解决方案

问题1:表达式构建错误

// 错误:直接拼接表达式
Expression<Func<User, bool>> exp1 = u => u.Age > 18;
Expression<Func<User, bool>> exp2 = u => u.Name.Contains("张");
// var wrong = exp1 || exp2; // 编译错误

// 正确:使用Expressionable组合
var correct = Expressionable.Create<User>()
    .And(exp1)
    .Or(exp2)
    .ToExpression();

问题2:空值处理

// 安全的空值处理
var exp = Expressionable.Create<User>();
if (!string.IsNullOrEmpty(searchKey))
{
    exp.And(u => u.Name.Contains(searchKey) || u.Email.Contains(searchKey));
}
// 如果没有条件,返回所有数据

问题3:性能优化

// 使用AsEnumerable()延迟执行复杂表达式
var complexQuery = db.Queryable<User>()
    .Where(u => u.IsActive)
    .AsEnumerable() // 切换到内存中处理
    .Where(u => ComplexBusinessLogic(u))
    .ToList();

总结与展望

SqlSugar的动态表达式查询功能为.NET开发者提供了强大的灵活性和表达能力。通过Expressionable<T>系列类,我们可以:

  1. 动态构建复杂查询条件,适应多变的业务需求
  2. 实现条件组合的模块化,提高代码可维护性
  3. 支持多表关联查询,满足复杂业务场景
  4. 提供性能优化机制,平衡灵活性与执行效率

在实际项目中,建议:

  • 对于简单固定条件,使用原生LINQ
  • 对于中等复杂度的动态条件,使用Expressionable
  • 对于极端复杂的查询,考虑分步处理或存储过程

随着.NET生态的不断发展,SqlSugar的动态表达式功能将继续演进,为开发者提供更强大、更高效的查询解决方案。掌握这一技能,将让你在数据处理领域游刃有余,轻松应对各种复杂的业务查询需求。

【免费下载链接】SqlSugar DotNetNext/SqlSugar: 这是一个用于SQL Server和MySQL的ORM框架。适合用于需要简化数据库操作的场景。特点:易于使用,支持多种数据库,具有代码生成和自动映射功能。 【免费下载链接】SqlSugar 项目地址: https://gitcode.com/DotNetNext/SqlSugar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

抵扣说明:

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

余额充值