SQL word wide "%like%" search in Entity Framework 6 using lambda expression

c# entity-framework entity-framework-6 linq

Question

I have a SQL query shown below and I have to write an equivalent query in Entity Framework in 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. In the given example, the search string is "Life-Span Development 16E 99 Subject Index". I have been trying to write c# code for this but unable to achieve the expected result. Could you please help me to convert the SQL query to Entity framework equivalent query?

SQL query:

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:

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();
}
1
1
7/16/2018 7:45:09 PM

Accepted Answer

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). It is the SQL equivalent of using OR.

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). It is the SQL equivalent of using AND.

2
7/16/2018 7:59:03 PM

Popular Answer

Based on the updated failure mode (too many results), change .Any to .All :

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow