我能够使用如下所示的 SQL 函数创建调用表达式
var likeMethod = typeof(DbFunctionsExtensions).GetMethod("Like", new[] { typeof(DbFunctions), typeof(string), typeof(string) });
Expression.Call(null, likeMethod, Expression.Constant(EF.Functions), searchKeyExpression, Expression.Constant($"%{filter.Value}%"));
我只需要了解如何将整数或小数列等列的功能与 Like 函数一起使用。 如果我使用上面的表达式,我会得到以下错误。我如何像使用非字符串数据类型一样使用带有 ef 的表达式
Argument Exeption: argument exception in Expression of System.Int32 can not be used for parameter for type System.String of method Boolean Like (Ef.DBfuntions)
重现步骤
var likeMethod = typeof(DbFunctionsExtensions).GetMethod("Like", new[] { typeof(DbFunctions), typeof(string), typeof(string) });
Expression.Call(null, likeMethod, Expression.Constant(EF.Functions), searchKeyExpression, Expression.Constant($"%{filter.Value}%"));
正如我所看到的,在下面的示例中有一个在 Ef.Functions Like 方法中执行此操作的选项
context.Set<MyEntity>().Where(e => EF.Functions.Like((string)(object)e.IntCol, "%1%"))
但是我如何使用成员表达式来做到这一点。
来源:- https://github.com/aspnet/EntityFrameworkCore/issues/9578
这是直线查询的解决方案。 https://github.com/aspnet/EntityFrameworkCore/issues/16195
更多技术细节
EF 核心版本:(ASP.NET 核心 2.1) 数据库提供者:(例如 Microsoft.EntityFrameworkCore.SqlServer) 操作系统: IDE:(例如 Visual Studio 2017 15.4)
最佳答案
“双重转换”(string)(object)e.IntCol
是一种欺骗 C# 编译器将 int
参数“传递”给期望 string
参数(如 EF.Functions.Like
)。当然,如果实际调用了该方法,您将在运行时得到无效的强制转换异常。
但这个技巧有效,因为这样的方法永远不会被“调用”,而是被转换为 SQL,并且 SqlServer EF Core 提供程序删除了此类转换并允许您使用 SqlServer 隐式数据转换。我在 How can a JSON_VALUE be converted to a DateTime with EF Core 2.2? 中使用相同的技术(尽管方向相反)和 Expression tree to SQL with EF Core .
这是如何映射到 Expression
方法的。给定 Expression searchKeyExpression
(具体的 Expression
类型无关紧要),重要的是 Expression.Type< 返回的
属性。如果它是 Type
/string
,你没问题,否则你需要对其应用 (string)(object)
强制转换,这是通过两个 Expression.Convert
调用。
像这样:
Expression matchExpression = searchKeyExpression;
if (matchExpression.Type != typeof(string))
{
matchExpression = Expression.Convert(matchExpression, typeof(object));
matchExpression = Expression.Convert(matchExpression, typeof(string));
}
var pattern = Expression.Constant($"%{filter.Value}%");
var callLike = Expression.Call(
typeof(DbFunctionsExtensions), "Like", Type.EmptyTypes,
Expression.Constant(EF.Functions), matchExpression, pattern);
关于c# - 带有 Linq 表达式的 EF Core SQL 函数 LIKE 方法不适用于非字符串类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56715091/