You need to enable JavaScript to run this app. Entity Framework仓储Get()方法如何基于指定属性实现动态过滤查询
优惠活动
大模型
产品
解决方案
定价
更多

Entity Framework仓储Get()方法如何基于指定属性实现动态过滤查询

实现方案

方案1:手动构建表达式树(无额外依赖,适合简单场景)

这种方案适合需求比较固定,仅需要支持少量属性和操作符的场景,不需要引入第三方依赖。
首先实现通用的过滤表达式构建方法:

using System.Linq.Expressions;
using System.Reflection;

public static Expression<Func<TEntity, bool>> BuildFilter<TEntity>(string propertyName, string operatorStr, object filterValue)
{
    // 构造Lambda参数 e => ...
    var parameter = Expression.Parameter(typeof(TEntity), "e");
    // 构造属性访问表达式 e.PropertyName
    var propertyAccess = Expression.Property(parameter, propertyName);
    // 构造值常量,自动匹配属性类型
    var constantValue = Expression.Constant(Convert.ChangeType(filterValue, propertyAccess.Type));

    // 根据操作符生成对应表达式
    Expression filterBody = operatorStr.ToLower() switch
    {
        "eq" => Expression.Equal(propertyAccess, constantValue),
        "ne" => Expression.NotEqual(propertyAccess, constantValue),
        "contains" => Expression.Call(propertyAccess, 
            typeof(string).GetMethod("Contains", new[] { typeof(string) })!, 
            constantValue),
        _ => throw new NotSupportedException($"暂不支持操作符:{operatorStr}")
    };

    // 组装为完整Lambda表达式返回
    return Expression.Lambda<Func<TEntity, bool>>(filterBody, parameter);
}

接下来只需要解析你传入的$filter查询字符串,调用上面的方法生成过滤表达式,再传入你现有的仓储Get方法即可:

// 示例:解析 $filter=Name eq 'XYZ'
string rawFilter = "Name eq 'XYZ'";
var filterSegments = rawFilter.Split(' ', StringSplitOptions.RemoveEmptyEntries);
string propertyName = filterSegments[0];
string op = filterSegments[1];
string value = filterSegments[2].Trim('\'');

// 生成Team实体的过滤表达式
var teamFilter = BuildFilter<Team>(propertyName, op, value);
// 调用现有仓储方法查询
var queryResult = _teamRepository.Get(filter: teamFilter);

方案2:使用第三方库(适合复杂过滤场景)

如果需要支持多属性组合过滤、嵌套逻辑、全量OData $filter语法,可以直接用成熟的类库,避免手写大量表达式树逻辑。

  1. 安装NuGet包 System.Linq.Dynamic.Core
Install-Package System.Linq.Dynamic.Core
  1. 直接用过滤字符串生成查询条件:
using System.Linq.Dynamic.Core;

// 直接解析字符串生成Where条件,支持参数化避免SQL注入
var filterResult = Entities.Where("Name == @0", "XYZ").ToList();

如果需要完全兼容OData的$filter、$orderby等参数规范,直接使用微软官方的Microsoft.AspNetCore.OData包即可自动完成参数解析和查询构造。

注意事项
  • 手写表达式树时必须对属性名、操作符做白名单校验,避免用户传入非法参数导致程序报错或数据泄露
  • 过滤逻辑是基于IQueryable生成的,会被EF转换为SQL在数据库端执行,不会将全量数据加载到内存后过滤,性能符合预期
  • 禁止直接拼接SQL字符串,所有过滤值都要走参数化逻辑,避免SQL注入风险

内容的提问来源于stack exchange,提问作者Jay Modi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 16:03:01