Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Contains在非英语文本的SQLite中搜索返回的结果比预期的多_C#_Wpf_Sqlite_Entity Framework 6 - Fatal编程技术网

C# 使用Contains在非英语文本的SQLite中搜索返回的结果比预期的多

C# 使用Contains在非英语文本的SQLite中搜索返回的结果比预期的多,c#,wpf,sqlite,entity-framework-6,C#,Wpf,Sqlite,Entity Framework 6,我在WPF应用程序中使用Sqlite+EF,当我在数据库中搜索包含非英语字母的文本时,我得到了我期望的行+另一行不知道它为什么出现。 我所做的是: dbContext.MyTable.Where(w=>w.Name.Contains(someNonEnglishTextHere)) DB是Sqlite3 编码是UTF-8 MyTable中的列Name具有CollateasNOCASE 我用的是EF6 当查看EF形成的sql查询时,包含由CHARINDEX重新计算的而不是LIKE,有没有办法强

我在WPF应用程序中使用Sqlite+EF,当我在数据库中搜索包含非英语字母的文本时,我得到了我期望的行+另一行不知道它为什么出现。 我所做的是:
dbContext.MyTable.Where(w=>w.Name.Contains(someNonEnglishTextHere))

  • DB是Sqlite3
  • 编码是UTF-8
  • MyTable
    中的列
    Name
    具有
    Collate
    as
    NOCASE
  • 我用的是EF6

当查看EF形成的sql查询时,
包含由
CHARINDEX
重新计算的
而不是
LIKE
,有没有办法强制EF使用
LIKE
?如果我能做到的话,也许这就是解决方案。

您可以通过注入db拦截器来重放CHARINDEX函数。 将拦截器添加到dbcontext

class MyDBContext: DbContext
{
    static MyDBContext()
    {
        DbInterception.Add(new SqliteInterceptor());
    }
}
像这样完成拦截器:

class SqliteInterceptor : IDbCommandInterceptor
{
    private static Regex replaceRegex = new Regex(@"\(CHARINDEX\((.*?),\s?(.*?)\)\)\s*?>\s*?0");

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        ReplaceCharIndexFunc(command);
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        ReplaceCharIndexFunc(command);
    }

    private void ReplaceCharIndexFunc(DbCommand command)
    {
        bool isMatch = false;
        var text = replaceRegex.Replace(command.CommandText, (match) =>
        {
            if (match.Success)
            {
                string paramsKey = match.Groups[1].Value;
                string paramsColumnName = match.Groups[2].Value;
                //replaceParams
                foreach (DbParameter param in command.Parameters)
                {
                    if (param.ParameterName == paramsKey.Substring(1))
                    {
                        param.Value = string.Format("%{0}%", param.Value);
                        break;
                    }
                }
                isMatch = true;
                return string.Format("{0} LIKE {1}", paramsColumnName, paramsKey);
            }
            else
                return match.Value;
        });
        if (isMatch)
            command.CommandText = text;
    }
}
类SqliteInterceptor:IDBComandInterceptor { 私有静态正则表达式replaceRegex=新正则表达式(@“\(CHARINDEX\(.*?\s?(.*?)\)\s*?>\s*?0”); public void NonQueryExecuted(DbCommand命令,DbCommandInterceptionContext interceptionContext) { } public void非查询执行(DbCommand命令,DbCommandInterceptionContext interceptionContext) { } public void ReaderExecuted(DbCommand命令,DbCommandInterceptionContext interceptionContext) { } public void reader执行(DbCommand命令,DbCommandInterceptionContext interceptionContext) { ReplaceCharIndexFunc(命令); } 已执行公共空标度(DbCommand命令、DbCommandInterceptionContext interceptionContext) { } public void scalare执行(DbCommand命令、DbCommandInterceptionContext interceptionContext) { ReplaceCharIndexFunc(命令); } 专用void ReplaceCharIndexFunc(DbCommand命令) { bool-isMatch=false; var text=replaceRegex.Replace(command.CommandText,(匹配)=> { 如果(匹配成功) { 字符串paramsKey=match.Groups[1]。值; 字符串paramsColumnName=match.Groups[2]。值; //替换参数 foreach(command.Parameters中的DbParameter参数) { if(param.ParameterName==paramsKey.Substring(1)) { param.Value=string.Format(“%{0}%”,param.Value); 打破 } } isMatch=true; 返回string.Format(“{0}类似于{1}”,paramsColumnName,paramsKey); } 其他的 返回match.Value; }); 如果(isMatch) command.CommandText=文本; } }
我通过重写函数解决了问题

 [SQLiteFunction(Arguments = 1, FuncType = FunctionType.Scalar, Name = "Lower")]
    class CustomLower : SQLiteFunction
    {
        public override object Invoke(object[] args)//characters for the growth of
        {
            return args[0].ToString().ToLower();
        }
    }

    [SQLiteFunction(Arguments = 2, FuncType = FunctionType.Scalar, Name = "CHARINDEX")]
    class CustomCharIndex : SQLiteFunction
    {
        public override object Invoke(object[] args)//characters for the growth of
        {
            return args[1].ToString().IndexOf(args[0].ToString(), StringComparison.Ordinal) + 1;
        }
    }

你解决了吗?我和西里尔语也有同样的问题…从来没有解决过,在内存中搜索,所以我可以摆脱在数据库中搜索。