问题描述
我尝试通过遵循this ticket中最受欢迎的答案并像下面这样创建它的本地实现来模拟DbFunctions.Like函数:
Callback = () => {
[...document.querySelectorAll(".gs-title")].forEach(el => {
el.innerHTML = el.innerHTML.replace(/SITENAME - /,"");
});
};
window.__gcse || (window.__gcse = {});
window.__gcse.searchCallbacks = {
web: {
rendered: "Callback",},};
并在查询中使用此函数代替System.Entity.DbFunctions:
public static class DbFunctions
{
[DbFunction("Edm","TruncateTime")]
public static DateTime? TruncateTime(DateTime? dateValue)
=> dateValue?.Date;
[DbFunction("Edm","Like")]
public static bool Like(string searchString,string likeExpression)
=> Regex.IsMatch(searchString,$"^{likeExpression.Replace("%",".*")}$");
[DbFunction("Edm","Right")]
public static string Right(string stringArgument,long? length)
=> stringArgument.Substring(stringArgument.Length - ((int?) length ?? 0));
}
它适用于例如“ TruncateTime”或“ Right”功能。
在调试解决方案时,将调用函数的sql版本,而在运行单元测试时,将调用本地的并通过测试。
当涉及到“ Like”时,我仍然收到NotSupportedException:
是否不可能像其他系统函数一样模拟DbFunctions?
我正在使用EF6 v6.4.4,Moq v4.14.1和nUnit v3.12.0。
解决方法
DbFunctions.Like没有DbFunctionAttribute,因此无法以这种方式进行模拟。作为解决方法,可以使用SqlFunctions.PatIndex。 PatIndex将返回给定模式在字符串中首次出现的位置,如果根本不出现,则返回0。
[DbFunction("SqlServer","PATINDEX")]
public static int? Like(string searchString,string likeExpression)
=> Regex.IsMatch(searchString,$"^{likeExpression.Replace("%",".*")}$") ? 1 : 0;
和
query = query.Where(x => valuesToSearch.Any(v => DbFunctions.Like(x.Number,v) > 0));
可以为您工作。不过,在可读性方面并不是很好。