DbFunctions 用于在 IQueryable 查询中调用数据库原生函数以实现查询下推,须通过 EF.Functions 在 Where/OrderBy/Select 中使用,不可在客户端执行或 .ToList() 后调用,不同数据库支持度不同,自定义函数需注册并确保数据库端存在。
EF Core 的 DbFunctions 用于在 LINQ 查询中调用数据库原生函数(如字符串处理、日期计算、数学运算等),让查询能下推到数据库执行,避免把大量数据拉到内存再处理。
EF Core 将常用数据库函数封装在 DbContext 的 EF.Functions 属性中。必须在 LINQ 查询的 Where、OrderBy、Select 等方法中使用,不能在 C# 代码中直接调用。
IQueryable(即未触发执行),否则会报错或回退到客户端计算Like 在 SQL Server 和 SQLite 中可用,但写法和行为可能略有差异以下是在 Where 或 Select 中的典型用法:
context.Users.Where(u => EF.Functions.Like(u.Name, "%admin%"))
EF.Functions.Collate(u.Name, "SQL_Lat
in1_General_CP1_CI_AS")
EF.Functions.DateDiffDay(u.CreatedAt, DateTime.Today) > 7
EF.Functions.Contains(u.Description, "error")
EF.Functions.ILike(u.Email, "[a-z]%@example.com")
如果内置函数不够用,可通过 ModelBuilder.HasDbFunction 注册自定义标量函数(需数据库已存在该函数):
CREATE FUNCTION dbo.CalculateAge)OnModelCreating 中注册:modelBuilder.HasDbFunction(typeof(MyDbFunctions).GetMethod(nameof(MyDbFunctions.CalculateAge)))
[DbFunction] 特性,EF 才能识别并翻译成 SQLDbFunctions 很实用,但也容易出错:
.ToList()、.AsEnumerable() 之后使用,否则会抛 InvalidOperationException
Random、NewId)每次查询结果可能不同,慎用于排序或分页EF.Functions 方法在 SQLite 下不可用或被模拟为客户端计算LogTo(Console.WriteLine))查看最终生成的 SQL,确认函数是否成功下推基本上就这些。用好 DbFunctions 能写出更高效、更贴近数据库能力的查询,关键是在 IQueryable 链路里用,别让它“漏”到内存里。