首页 新闻 会员 周边

EF DBFirst Linq 在Sqlite 下的Contains 解释似乎有问题

0
[待解决问题]

var cc = db.WX_UserInfo.Where(x => x.UserInfo_Name.Contains(nickname));

 

test1 模糊查询

nickname = 落雨

查询出来的结果不匹配:贾键 这样的字符串也能在查询结果中

正确结果应该只有两个

test2 输全名

nickname = 落雨伤情

查询出来的结果匹配,只有两个

不知道博友有没有遇到过这样的问题

 

SELECT
[Extent1].[UserInfo_ID] AS [UserInfo_ID],
[Extent1].[ChatroomList_ID] AS [ChatroomList_ID],
[Extent1].[UserInfo_Header] AS [UserInfo_Header],
[Extent1].[UserInfo_WXID] AS [UserInfo_WXID],
[Extent1].[UserInfo_Country] AS [UserInfo_Country],
[Extent1].[UserInfo_Province] AS [UserInfo_Province],
[Extent1].[UserInfo_City] AS [UserInfo_City],
[Extent1].[UserInfo_Signature] AS [UserInfo_Signature],
[Extent1].[UserInfo_Name] AS [UserInfo_Name],
[Extent1].[UserInfo_Tag] AS [UserInfo_Tag],
[Extent1].[Chatroom_WXID] AS [Chatroom_WXID]
FROM [WX_UserInfo] AS [Extent1]
WHERE (CHARINDEX(@p__linq__0, [Extent1].[UserInfo_Name])) > 0

 

这是解释的T-SQL

问题补充:

这是断点之后的截图,和代码完整截图

 

之后再测试Indexof发现结果一样,也没有得到理想的结果

TommyBiteMe的主页 TommyBiteMe | 菜鸟二级 | 园豆:204
提问于:2017-02-22 16:07
< >
分享
所有回答(3)
0

看了一下我愣是没理解你想表达什么

MrNice | 园豆:3450 (老鸟四级) | 2017-02-22 16:31

问题是这样的:

var gg = db.WX_UserInfo.ToList();
var hh = gg.Where(x => x.UserInfo_Name.Contains(nickname));

var cc = db.WX_UserInfo.Where(x => x.UserInfo_Name.Contains(nickname));

这样的结果是不一样的,上面那种得到的结果是我想要的,下面这个得到的结果不是我所想要的,我想问的是这是不是一个sqlite的ef组件的一个bug?

支持(0) 反对(0) TommyBiteMe | 园豆:204 (菜鸟二级) | 2017-02-22 16:36

不知道博友有没有理解我的意思?

支持(0) 反对(0) TommyBiteMe | 园豆:204 (菜鸟二级) | 2017-02-22 16:41
0

Anyway,自己解决,这个不算是bug应该是EF解释的CHARINDEX函数在sqlite里面并不支持所以导致查询出来的结果错误,至于为什么能查出数据来这一点我很奇怪,我觉得可能是解释是这样的:可是似乎解释不通,在System.Data.SQLite.DLL是存在CHARINDEX这个函数的,对于这一点任然有疑惑,继续探究TAT

TommyBiteMe | 园豆:204 (菜鸟二级) | 2017-02-22 17:10

Contains转换后,变成charindex 变不是 like  '%?%',这样中文查找数据不正确

请问你的解决方法是直接执行SQL吗?

支持(0) 反对(0) Fzero | 园豆:200 (初学一级) | 2017-04-21 15:48
0

兄弟,我也遇到这个问题了,貌似和 TommyBiteMe 说的一样,不过我们可以自己写一个拦截器啊,拦截替换就可以了。

    public 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;
        }
    }

 

在dbcontext中添加这个拦截器

 

        public QiuTanDb() : base("name=defaultConn")
        {
            DbInterception.Add(new SqliteInterceptor());
        }
梦里的畅泳 | 园豆:159 (初学一级) | 2017-12-29 16:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册