You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中创建适配Entity Framework的自定义Like Expression

实现方案

核心说明

.NET 原生表达式树没有内置Like二元运算符,所以无法直接返回标准BinaryExpression实例,但我们可以构造EF可识别的方法调用表达式,完全适配你现有字典的Func<Expression, Expression, Expression>类型要求。

EF Core 版本实现

先引用必要命名空间:

using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;

方法实现代码:

public static Expression Like(Expression left, Expression right)
{
    // 反射获取EF.Functions.Like方法
    var likeMethod = typeof(DbFunctionsExtensions)
        .GetMethod(nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), left.Type, right.Type })
        ?? throw new InvalidOperationException("未找到匹配的EF.Functions.Like方法");
    
    // 构造方法调用表达式,EF查询翻译时会自动转为SQL LIKE语句
    return Expression.Call(
        null,
        likeMethod,
        new Expression[] { Expression.Constant(EF.Functions), left, right }
    );
}

添加到你的表达式字典即可使用:

var expressions = new Dictionary<string, Func<Expression, Expression, Expression>>
{
    { "is equal to", Expression.Equal },
    { "greater than", Expression.GreaterThan },
    { "like", Like }
};

EF 6 版本实现

如果使用的是.NET Framework版本的EF 6,改用SqlFunctions.PatIndex实现:

using System.Linq.Expressions;
using System.Data.Entity.SqlServer;

public static Expression Like(Expression left, Expression right)
{
    var patIndexMethod = typeof(SqlFunctions)
        .GetMethod(nameof(SqlFunctions.PatIndex), new[] { typeof(string), typeof(string) })
        ?? throw new InvalidOperationException("未找到匹配的SqlFunctions.PatIndex方法");
    
    // PatIndex返回匹配位置,大于0即匹配成功,等价于LIKE
    var patIndexCall = Expression.Call(patIndexMethod, right, left);
    return Expression.GreaterThan(patIndexCall, Expression.Constant(0));
}

关于返回BinaryExpression的说明

如果必须严格遵循返回BinaryExpression的签名,你需要自定义派生自BinaryExpression的自定义表达式类型,同时配合自定义表达式访问器在查询翻译前做表达式替换,常规业务场景下不需要这么做,上面的实现已经可以直接正常工作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 00:06:08