Linq to Entities - 复杂的搜索匹配条件

时间:2017-02-02 10:20:52

标签: c# sql linq linq-to-entities

我在数据库中有一个对象表,每个对象都有一个键/值对字典作为与之关联的元数据。我需要能够将一个搜索条件列表传递给我的函数,并返回每个匹配的结果,包括通配符。例如传入

姓名:" TEST%" 版本:" 1" 创作者:" jamesk"

应返回jamesk创建的所有对象,版本1和名称以TEST开头。

我的代码如下

itemsFound = (from h in _objectStoreRepository.GetHeaders()
       where
        (from i in h.Items
         where i.CreatedAt <= request.AsAtTime &&
               (from f in request.SearchFilters select f)
                   .All(f =>
                        (from mdp in i.MetaDataPairs
                         where mdp.Key.ToLower() == f.Key.ToLower() &&
                         mdp.Value.ToLower().Like(f.Value.ToLower())
                         select mdp).Any()
                    )          
          select i).Any()
         select h).ToList();

如果可能的话,我想在一个查询中完成所有操作但是试图让Linq到实体一次完成所有事情都证明是艰难的。以上返回以下错误。

  

错误:获取对象失败。错误无法创建常量   类型的价值   &#39; System.Collections.Generic.KeyValuePair`2 [[System.String,mscorlib,   版本= 4.0.0.0,文化=中立,   PublicKeyToken = b77a5c561934e089],[System.String,mscorlib,   Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]&#39;。   此处仅支持原始类型或枚举类型   上下文。

我想我理解了这个问题,我试图在request.SearchFilters中创建一个用于我的LINQ to Entities查询语法的集合,这是一个字典,但它说它只能从原始值创建一个集合。

我理解这一点,但我无法看到如何实现我需要做的事情,因为我需要匹配该对的键和值。

有人可以建议如何让这个工作吗?

更新:我进一步了解,将KVP分成如下

itemsFound = (from h in _objectStoreRepository.GetHeaders()
           where
            (from i in h.Items
             where i.CreatedAt <= request.AsAtTime &&
               (from f in request.SearchFilters.Keys select f)
                   .All(k => 
                       (from mdp in t.TradeMetaDataPairs
                        where mdp.Key.ToLower() == k.ToLower() &&
                        mdp.Value.ToLower().Like(request.SearchFilters[k].ToLower())
                           select mdp).Any()
                         )                                                      
                      select t).Any()
                   select th).ToList();

这似乎被接受,但我现在遇到的问题是我的扩展方法Like()不被接受。

我写这篇是因为我需要模拟SQL&#34;喜欢&#34;查询,没有办法做到这一点。仅包含模拟%x%,startswith仅模拟x%,endswith仅模拟%x,没有任何模拟x%x。此外,我在一个声明中需要它们。为什么linq对实体没有直接支持SQL LIKE?它本机的SQL函数,当然应该支持: - /

更新2:添加了我喜欢的方法

 public static class LikeStringExtension
    {
        public static bool Like(this string toSearch, string toFind)
        {
            return new Regex(@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(toFind, ch => @"\" + ch).Replace('_', '.').Replace("%", ".*") + @"\z", RegexOptions.Singleline).IsMatch(toSearch);
        }        
    }

0 个答案:

没有答案