LINQ to SQL - select where text like string array

萝らか妹 提交于 2019-12-03 00:29:53

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)

kind of new to the whole LINQ to SQL game, but does this syntax help?

string[] items = new string[] { "a", "b", "c", "d" };

var items = from i in db.Items
             where items.Contains(p.text)
            select i;

Got it from:

http://blog.wekeroad.com/2008/02/27/creating-in-queries-with-linq-to-sql/

After reading this post, looking for the same solution as you, I found a solution using the .Any and .All methods for Linq are a nice simple and elegant way to get matching results for arrays.

In this instance I'm using a search input, separated by commas as an example. I don't care if the match is not in the same case.

var qry = Query.Split(',').Select(c => c.Trim().ToLower());

First Get some data to query, from Linq to SQL or wherever

var search = db.tablename;

Using the lambda syntax for nice tight code, and result in matches to .Any string in the query to either the name or description in the table.

search = search.Where(
    record => 
    qry.Any(q => record.Name.ToLower().Contains(q)) || 
    qry.Any(q => record.Description.ToLower().Contains(q)));

If you want only results where all strings are matched within any field you can replace .Any with .All:

search = search.Where(
    record => 
    qry.All(q => record.Name.ToLower().Contains(q)) || 
    qry.All(q => record.Description.ToLower().Contains(q)));

Using:

string searh = "test1 test2,test3";    
data.Persons.Search(p => p.Name, search);

Search function is:

public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string s)
{
    if (string.IsNullOrEmpty(s))
        return source;

    string[] str = s.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);

    MethodInfo methodContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });

    Expression strExpression;
    Expression expressionContains;
    Expression resultExpression = Expression.Empty();

    for (int i = 0; i < str.Length; i++)
    {
        strExpression = Expression.Constant(str[i].Trim(), typeof(string));
        expressionContains = Expression.Call(selector.Body, methodContains, strExpression);

        if (i == 0)
            resultExpression = expressionContains;
        else
            resultExpression = Expression.OrElse(resultExpression, expressionContains);
    }

    Expression<Func<T, bool>> lambdaExpr = Expression.Lambda<Func<T, bool>>(resultExpression, new ParameterExpression[] { selector.Parameters[0] });

    return source.Where(lambdaExpr);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!