Search code examples
sqllinqlinq-to-sqlsql-like

LINQ to SQL - select where text like string array


I have a List<string> of variable count, and I want to query (via LINQ) a table to find any items that contain any of those strings in the Text column.

Tried this (doesn't work):

items = from dbt in database.Items
         where (stringList.FindAll(s => dbt.Text.Contains(s)).Count > 0)
         select dbt;

Query would be something like:

select * from items where text like '%string1%' or text like '%string2%'

Is this possible?


Solution

  • Check this article out to do what you want:
    http://www.albahari.com/nutshell/predicatebuilder.aspx

    This works like a dream. I essentially cut and pasted their code and got this back (with my own data-scheme of course):

    SELECT [t0].[Id], [t0].[DateCreated], [t0].[Name] ...
    FROM [dbo].[Companies] AS [t0]
    WHERE ([t0].[Name] LIKE @p0) OR ([t0].[Name] LIKE @p1)
    

    Here is the code I ran for the proof of concept:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Linq.Expressions;
    
    namespace PredicateTest
    {
    class Program
    {
        static void Main(string[] args)
        {
            DataClasses1DataContext dataContext = new DataClasses1DataContext();
    
            Program p = new Program();
            Program.SearchCompanies("test", "test2");
            var pr = from pi in  dataContext.Companies.Where(Program.SearchCompanies("test", "test2")) select pi;
        }
    
        DataClasses1DataContext dataContext = new DataClasses1DataContext();
    
        public static Expression<Func<Company, bool>> SearchCompanies(
                                                      params string[] keywords)
        {
            var predicate = PredicateBuilder.False<Company>();
            foreach (string keyword in keywords)
            {
                string temp = keyword;
                predicate = predicate.Or(p => p.Name.Contains(temp));
            }
            return predicate;
        }
    
    }
    
    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
    
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }
    
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }
    }
    

    I'd suggest going to the site for the code and explanation.

    (I am leaving the first answer because it works well if you need an IN statement)