能够使用如下所示的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与非字符串数据类型一起使用表达式
自变量示例:System.Int32表达式中的自变量异常不能用于方法类型为Boolean Like(Ef.DBfuntions)的System.String类型的参数
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 Core版本:(ASP.NET Core 2.1) 数据库提供程序:(例如Microsoft.EntityFrameworkCore.SqlServer) 操作系统: IDE :(例如Visual Studio 2017 15.4)
答案 0 :(得分:3)
“双重强制转换” (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
类型无关紧要),重要的是Type
属性返回的Expression.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);