简体   繁体   English

SQL字宽“%like%”使用lambda表达式在Entity Framework 6中搜索

[英]SQL word wide “%like%” search in Entity Framework 6 using lambda expression

I have a SQL query shown below and I have to write an equivalent query in Entity Framework in C#. 我有一个SQL查询如下所示,我必须在C#中的实体框架中编写一个等效的查询。 I have to make a join between to tables and I have to use SQL LIKE operator with each word in the search string. 我必须在表之间建立连接,并且我必须对搜索字符串中的每个单词使用SQL LIKE运算符。 In the given example, the search string is "Life-Span Development 16E 99 Subject Index". 在给定的示例中,搜索字符串是“Life-Span Development 16E 99 Subject Index”。 I have been trying to write c# code for this but unable to achieve the expected result. 我一直在尝试为此编写c#代码但无法达到预期的结果。 Could you please help me to convert the SQL query to Entity framework equivalent query? 你能帮我把SQL查询转换成Entity框架等价查询吗?

SQL query: 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# code: * 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();
}

This is the source of your problem: 这是您的问题的根源:

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

Any() returns true if one match is found (or more, but it stops checking after one). 如果找到一个匹配(或更多,但在一个匹配后停止检查), Any()将返回true。 It is the SQL equivalent of using OR . 它是使用OR的SQL等价物。

What you want is this: 你想要的是这个:

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

All() returns true if all elements (in searchTextArray ) have a match (in thise case, if all searchTextArray elements are contained in a given title ). All()如果所有元素(返回true searchTextArray )有符合(在thise情况下,如果所有searchTextArray元素都包含在一个给定的title )。 It is the SQL equivalent of using AND . 它是使用AND的SQL等价物。

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

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

A bit clunky but it does the job 有点笨重,但它做的工作

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();
        }
    }
}

yields 产量

TRUE 真正
FALSE
TRUE 真正

You may use SqlMethods.Like . 您可以使用SqlMethods.Like

update your searchText variable as - 将您的searchText变量更新为 -

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

remove this code line - 删除此代码行 -

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

then update the Where condition in results as 然后将resultsWhere条件更新为

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM