【问题标题】:SQL word wide "%like%" search in Entity Framework 6 using lambda expression使用 lambda 表达式在实体框架 6 中进行 SQL 字宽“%like%”搜索
【发布时间】:2018-07-17 04:28:54
【问题描述】:

我有一个如下所示的 SQL 查询,我必须在 C# 的实体框架中编写一个等效的查询。我必须在表之间进行连接,并且必须对搜索字符串中的每个单词使用 SQL LIKE 运算符。在给定的示例中,搜索字符串是“Life-Span Development 16E 99 Subject Index”。我一直在尝试为此编写 c# 代码,但无法达到预期的结果。能否请您帮我将 SQL 查询转换为实体框架等效查询?

SQL 查询:

SELECT 
    [titles].[title],
    [assets].[filename]
FROM 
    titles 
INNER JOIN 
    assets ON titles.ID = assets.ID 
WHERE 
    (title LIKE '%Life-Span%' 
     AND title LIKE '%Development%' 
     AND title LIKE '%16E%' 
     AND title LIKE '%99%' 
     AND title LIKE '%Subject%' 
     AND title LIKE '%Index%')

*C#代码:

static void Main(string[] args)
{
    string searchText = "Life-Span Development 16E 99 Subject Index";

    using (Entities db = new Entities())
    {
        var result = db.titles
                    .Join(db.assets,
                            p => p.tid,
                            e => e.tid,
                            (p, e) => new {
                                 title = p.title1,
                                 fileName = e.filename
                            });               

        var searchTextArray = searchText.ToLower().Split(' ');
        result = result.Where(t => searchTextArray.Any(s => t.title.ToLower().Contains(s)));

        foreach(var item in result)
        {
            Console.WriteLine(string.Format("Title = {0} and finename = {1}", item.title, item.fileName));
        }
    }

    Console.ReadKey();
}

【问题讨论】:

  • 这可以编译吗?看起来 foreach 不能与 var 一起使用?
  • @AlexanderToptygin 它编译并运行。对于每个使用 var 的作品都没有任何问题。
  • @Simant 有用吗?如果没有,它怎么行不通?
  • 那么,您需要获得多大的动态?因为作为基本情况,您总是可以 db.SqlQuery("SELECT......").ToList();
  • @Simant 你试过用 .All(....) 代替 .Any 吗?

标签: c# entity-framework linq entity-framework-6


【解决方案1】:

这是您问题的根源:

result = result.Where(t => searchTextArray.Any(s => t.title.ToLower().Contains(s)));

Any() 如果找到 一个 匹配项(或更多,但在一个匹配项后停止检查),则返回 true。它相当于使用OR 的SQL。

你想要的是这个:

result = result.Where(t => searchTextArray.All(s => t.title.ToLower().Contains(s)));
如果 所有 元素(在searchTextArray 中)匹配(在这种情况下,如果所有searchTextArray 元素都包含在给定的title 中),

All() 返回 true。它相当于使用AND 的SQL。

【讨论】:

    【解决方案2】:

    根据更新的故障模式(结果太多),将 .Any 改为 .All :

        result = result.Where(t => searchTextArray.All(s => t.title.ToLower().Contains(s)));
    

    【讨论】:

      【解决方案3】:

      有点笨拙,但它可以完成这项工作

      namespace Like
      {
          class Program
          {
              static bool Is(char a, char b)
              { 
                    return a == b || 
                    char.ToUpper(a) == b || 
                    char.ToUpper(b) == a;
              }
              static bool IsLike(string sample, string query)
              {
                  int k = 0;
                  foreach (char c in sample)
                  {
                      if (!Is(c, query[k]))
                      {
                          k = 0;
                          continue;
                      }
                      if (++k == query.Length)
                          return true;
                  }
                  return false;
              }
      
              static void Main(string[] args)
              {
                  string testSample = "This is a str1ng 0f charac7er5";
                  Console.WriteLine(IsLike(testSample, "this"));
                  Console.WriteLine(IsLike(testSample, "of"));
                  Console.WriteLine(IsLike(testSample, "chAra"));
                  Console.ReadKey();
              }
          }
      }
      

      产量

      真的
      错误
      真的

      【讨论】:

        【解决方案4】:

        您可以使用SqlMethods.Like

        将您的 searchText 变量更新为 -

        string searchText = "Life-Span%Development%16E%99%Subject%Index";
        

        删除此代码行 -

        var searchTextArray = searchText.ToLower().Split(' ');
        

        然后将results 中的Where 条件更新为

        results = from r in results 
                      where SqlMethods.Like(r.title,searchText )
                      select r;
        

        【讨论】:

        • 这是针对 LINQ to SQL 的,这个查询是针对 EF 的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 1970-01-01
        • 1970-01-01
        • 2018-11-21
        相关资源
        最近更新 更多