c# - 实体框架核心中等效的 SQL RIGHT 函数
问题描述
我正在处理一个 Net Core 项目,使用实体框架、mysql 数据库和 pomelo 框架。我需要执行此查询,以便将模型中属性的最后 X 个字符与模式进行比较:
_context.Cars
.Where(c => EF.Functions.Like(c.CarName.ToString().Right(5), pattern))
.ToList();
我想知道实体框架核心中是否有任何等效的 SQL RIGHT 函数。
提前致谢
解决方案
更新(EF Core 5.0+):
EF Core 5.0 引入了IsBuiltIn
属性 onDbFunctionAttribute
和IsBuiltIn(bool)
fluent API,因此不再需要提供翻译。最小映射与 EF Core 2.x 中的相同,只是
[DbFunction("RIGHT", "")]
被替换为
[DbFunction("RIGHT", IsBuiltIn = true, IsNullable = true)]
EF Core 5 还允许根据其参数配置用户定义函数的可空性,但只能流畅地完成,因此您可以考虑使用显式映射而不是通用代码。例如
public static class MyDbFunctions
{
public static string Right(this string s, int length)
=> throw new InvalidOperationException();
public static void Register(ModelBuilder modelBuider)
{
var fb = modelBuilder.HasDbFunction(() => Right(default, default))
.HasName("RIGHT").IsBuiltIn(true).IsNullable(true);
fb.HasParameter("s").PropagatesNullability(true);
}
}
更新(EF Core 3.0+):
从 Ef Core 3.0 开始,空字符串模式被视为与 相同null
,即将默认模式添加到函数名称。这样,如果要添加内置功能,则必须提供“翻译”(奇怪的决定)。
所以你需要添加
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
并修改代码如下
modelBuider.HasDbFunction(dbFunc).HasTranslation(args =>
SqlFunctionExpression.Create(dbFunc.Name, args, dbFunc.ReturnType, null));
原来的:
由于目前既没有 CLRstring
也没有EF.Functions
方法调用Right
,答案是 EF Core 目前不提供等效的 SQLRIGHT
函数。
幸运的是,EF Core 允许您使用 EF Core 2.0 引入的数据库标量函数映射来添加它。
例如,添加以下类:
using System;
using System.Linq;
namespace Microsoft.EntityFrameworkCore
{
public static class MyDbFunctions
{
[DbFunction("RIGHT", "")]
public static string Right(this string source, int length)
{
if (length < 0) throw new ArgumentOutOfRangeException(nameof(length));
if (source == null) return null;
if (length >= source.Length) return source;
return source.Substring(source.Length - length, length);
}
public static void Register(ModelBuilder modelBuider)
{
foreach (var dbFunc in typeof(MyDbFunctions).GetMethods().Where(m => Attribute.IsDefined(m, typeof(DbFunctionAttribute))))
modelBuider.HasDbFunction(dbFunc);
}
}
}
(稍后您可以根据需要添加更多类似的功能)。
Register
然后从您的上下文OnModelCreating
覆盖添加调用:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// ...
MyDbFunctions.Register(modelBuilder);
// ...
}
你完成了。现在您应该可以使用所需的:
_context.Cars
.Where(c => EF.Functions.Like(c.CarName.ToString().Right(5), pattern))
.ToList();
推荐阅读
- android - 在构造函数 Kotlin 中使用泛型作为参数
- visual-studio-2019 - Visual Studio 2019 是否有 Monokai 语法突出显示
- python-3.x - 理解 keras model.summary()
- d3.js - d3 等值线图只显示一种颜色
- mysql - 连接失败后恢复mysqldump
- android - 是否可以在 Android 上设置启动画面的夜间预选赛?
- node.js - Foursquare API - 无法让用户(我自己的)签入历史记录
- c++ - Clang 说 is_same_v 的用法
不是 constexpr,不知道怎么不是 - google-apps-script - 使用 Appscript 将 Markdown 文本文件转换为 Google 文档?
- arrays - 如何从多个文件中读取同一列并将其收集到一个数组中