c# - EF Core 3 - 在 Where 子句中使用字符串的扩展方法
问题描述
我有一个简单的字符串扩展方法:
public static class FrenchStringExtensions
{
public static string ReplaceAccents(this string str)
{
return str
.Replace("ç", "c")
.Replace("é", "e")
.Replace("ê", "e")
.Replace("è", "e")
.Replace("ë", "e")
.Replace("â", "a")
.Replace("à", "a")
.Replace("î", "i")
.Replace("ï", "i")
.Replace("ô", "o")
.Replace("û", "u")
.Replace("ù", "u")
.Replace("ü", "u");
}
}
当我尝试在这样的Where()
子句中调用此方法时:
var supportTeamsQuery = this.MasterContext.IncidentSupportTeams
.AsNoTracking()
.IsActive();
if (!string.IsNullOrEmpty(pattern))
{
pattern = pattern.ToLower().ReplaceAccents().Trim();
supportTeamsQuery = supportTeamsQuery
.Where(st =>
st.Name.ToLower().ReplaceAccents().Contains(pattern)
);
}
我有一个错误:无法翻译 LINQ 表达式...
如果我Replace()
在内部使用调用,Where()
它工作正常。例如:
supportTeamsQuery = supportTeamsQuery
.Where(st =>
st.Name
.ToLower()
.Replace("ç", "c")
.Replace("é", "e")
.Replace("ê", "e")
...
.Contains(pattern)
);
但是我的代码中有几个地方需要以这种方式转换字符串,所以我想将它移到一个单独的方法中。
有没有可能让它工作?
解决方案
这里的不同之处在于,当您在Where
子句中内联方法时,编译器会生成带有多个 Replace 调用的 Expression Tree。当您调用时ReplaceAccents
,编译器仅生成此调用,EF 无法访问该方法的主体。所以你需要一种扩展表达式树的方法。
有很多解决方案可以做到这一点。但是试试这个扩展,它是为此而设计的。 https://github.com/axelheer/nein-linq/
根据文档,您必须进行以下代码更改:
public static class FrenchStringExtensions
{
[InjectLambda]
public static string ReplaceAccents(this string str)
{
_replaceAccentsFunc ??= ReplaceAccents().Compile();
return _replaceAccentsFunc(str);
}
Func<string, string> _replaceAccentsFunc;
private static Expression<Func<string, string>> ReplaceAccents()
{
return str =>
.Replace("ç", "c")
.Replace("é", "e")
.Replace("ê", "e")
.Replace("è", "e")
.Replace("ë", "e")
.Replace("â", "a")
.Replace("à", "a")
.Replace("î", "i")
.Replace("ï", "i")
.Replace("ô", "o")
.Replace("û", "u")
.Replace("ù", "u")
.Replace("ü", "u");
}
}
然后您可以在ToInjectable()
通话后使用您的功能
var supportTeamsQuery = this.MasterContext.IncidentSupportTeams
.ToInjectable()
.AsNoTracking()
.IsActive();
if (!string.IsNullOrEmpty(pattern))
{
pattern = pattern.ToLower().ReplaceAccents().Trim();
supportTeamsQuery = supportTeamsQuery
.Where(st =>
st.Name.ToLower().ReplaceAccents().Contains(pattern)
);
}
推荐阅读
- swift - 如何在不破坏其他单元格的情况下为集合视图插入设置动画?
- r - 如何在 R bookdown 文档中有一个 toc_float?
- java - 二次规划的舍入问题
- reactjs - 如何使用 if 和 else 语句更改 react-table 内的按钮?
- sql - 使用 R 以编程方式将变量名称及其数据类型写入 Teradata?
- c - c中的回文问题
- flutter - Flutter:从托管解析 json 时,类型“String”不是“int”类型的子类型
- c - 如何解决 MISRA C:2012 规则 11.6?
- dart - 周期性流不发送数据
- android - 为什么将产品风味添加到我的库 build.gradle 文件会导致我的本地应用程序无法解析从所述库导入的依赖项?