如何编写此扩展方法以由 EF Core 转换为 SQL Server?

Posted

技术标签:

【中文标题】如何编写此扩展方法以由 EF Core 转换为 SQL Server?【英文标题】:How to write this extension method to be translatable by EF Core to SQL Server? 【发布时间】:2021-11-24 02:02:01 【问题描述】:

我在我的 .NET 代码中有这个扩展方法检查字符串是否是什么东西:

public static bool IsSomething(this string text)

   var isNothing = string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text);
   return !isNothing;

但是,我不能在我的 EF Core quereis 中使用它:

dbset.Where(i => i.Title.IsSomething()); // throws non-translatable error

我知道我可以将查询重写为:

dbset.Where(i => i.Title != null && i.Title.Trim() != ""); // this works, but it's too verbose

但我真的不想写那么长的非描述性代码。

我怎样才能让IsSomething 可用于 SQL Server 翻译?

【问题讨论】:

旁注:IsNullOrWhiteSpace 为 null 或空字符串返回 true,这就是你所需要的 如果你想引入自己的扩展方法,你必须告诉EF如何翻译它们。见this article 【参考方案1】:

只需使用IsNullOrWhiteSpace;它做了IsNullOrEmpty 所做的事情:

如果 value 参数为 null 或 Empty,或者 value 仅由空白字符组成,则返回 true-- IsNullOrWhiteSpace 的文档

它被EF Core映射到一个SQL

@value IS NULL OR LTRIM(RTRIM(@value)) = N''

请注意,在 EF Core 6 中,这已更改为 @value IS NULL OR value= N'' - 相同; SQLS 忽略字符串 comp 中的尾随空格

这意味着您的IsSomething 方法实际上是!IsNullOrWhiteSpace,如果您使用它,EF 将翻译它..

【讨论】:

【参考方案2】:

您不能将此方法转换为 SQL Server。但是,您可以使用返回表达式的方法。例如:

public static Expression<Func<Student, bool>> IsSomething()

    return (s) => string.IsNullOrEmpty(s.FirstName) || string.IsNullOrWhiteSpace(s.FirstName);

通常,您应该在使用方法之前调用 AsEnumerable:

dbset.AsEnumerable().Where(i => i.Title.IsSomething());

但它会从数据库中加载所有实体。

【讨论】:

以上是关于如何编写此扩展方法以由 EF Core 转换为 SQL Server?的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有 LEFT JOIN 的 SQL 转换为 EF CORE 3 LINQ

如何比较 EF Core 插值查询中的整数列表

对EF Core进行扩展使支持批量操作/复杂查询

如何编写用于将分隔字符串转换为列表的通用扩展方法?

第15章 使用EntityFramework Core进行配置和操作数据 I

将“SELECT TOP (1) WITH TIES”转换为 EF Core