2009-02-04 30 views
7

Tôi có danh sách <string> số biến và tôi muốn truy vấn (qua LINQ) bảng để tìm bất kỳ mục nào chứa bất kỳ chuỗi nào trong cột Văn bản.LINQ to SQL - chọn văn bản như mảng chuỗi

cố gắng này (không hoạt động):

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

Query sẽ là một cái gì đó như:

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

Đây có phải là có thể?

Trả lời

11

Kiểm tra bài viết này ra để làm những gì bạn muốn:
http://www.albahari.com/nutshell/predicatebuilder.aspx

này hoạt động giống như một giấc mơ. Tôi chủ yếu cắt và dán mã của họ và nhận được trở lại này (với tôi dữ liệu chương trình riêng của khóa học):

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

Đây là mã tôi chạy cho bằng chứng của khái niệm:

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

tôi d đề nghị truy cập trang web để biết mã và giải thích.

(Tôi để lại câu trả lời đầu tiên bởi vì nó hoạt động tốt nếu bạn cần một tuyên bố IN)

6

loại mới cho toàn bộ trò chơi LINQ to SQL, nhưng cú pháp này có hữu ích không?

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/

+0

Đó chắc chắn nên làm việc –

+3

Cảm ơn ý tưởng Matthew, nhưng điều đó tạo ra các SQL sau đây:.. CHỌN [t0] [Text] FROM [dbo] [Bảng] AS [t0] ĐÂU [t0 ]. [Văn bản] IN (@ p0) Tìm kiếm cột văn bản trong mỗi mục của mảng thay vì tìm kiếm từng mục của mảng trong cột văn bản. – bjallen

1

Sau khi đọc bài này, tìm kiếm các giải pháp tương tự như bạn, tôi tìm thấy một giải pháp sử dụng các .Any.All phương pháp LINQ là một cách đơn giản và thanh lịch để có được kết quả phù hợp cho mảng.

Trong trường hợp này, tôi đang sử dụng đầu vào tìm kiếm, được phân tách bằng dấu phẩy làm ví dụ. Tôi không quan tâm nếu trận đấu không phải là trong cùng một trường hợp.

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

Đầu Nhận được một số dữ liệu để truy vấn, từ LINQ to SQL hoặc bất cứ nơi nào

var search = db.tablename; 

Sử dụng cú pháp lambda cho mã chặt chẽ tốt đẹp, và kết quả là trận đấu để .Any chuỗi trong truy vấn cho một trong hai tên hoặc mô tả trong bảng.

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

Nếu bạn muốn chỉ kết quả mà tất cả các chuỗi được kết hợp trong lĩnh vực bất kỳ, bạn có thể thay thế .Any với .All:

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

Sử dụng:

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

chức năng tìm kiếm là:

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