2009-02-04 24 views
7

我有一个List变量count的列表<string>,我想查询(通过LINQ)一个表来查找任何包含任何这些字符串的文本列中的项目。LINQ to SQL - 选择文本像字符串数组的地方

尝试这种(不工作):

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

查询会是这样的:

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

这可能吗?

回答

11

本文取出来做你想要什么:
http://www.albahari.com/nutshell/predicatebuilder.aspx

这就像一个梦。我基本上是剪切和粘贴自己的代码,并得到这个回来(当然是我自己的数据方案):

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

这是我跑了概念证明代码:

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

我d建议去网站查看代码和解释。

(我离开第一个答案,因为它工作得很好,如果你需要一个在报表)

1

阅读这篇文章,寻找同样的解决方案,你后,我发现使用了.Any.All方法解决方案Linq是获得数组匹配结果的简单而优雅的方法。

在这个例子中,我使用了一个搜索输入,以逗号分隔。我不在乎比赛是不是在相同的情况下。

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

先得到一些数据查询,从LINQ到SQL或其他地方

var search = db.tablename; 

使用了漂亮的紧身代码的lambda语法,并导致比赛以.Any字符串中的查询在该名称或表中的说明。

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

如果你只想要结果,所有的字符串任何领域内的匹配可以用.All替代.Any

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

使用:

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

搜索功能为:

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