Vì bạn đang làm việc w/LINQ Tôi cho rằng bạn đang làm việc với bối cảnh dữ liệu LINQ-to-SQL phải không? Tôi không có một DataContext dự phòng nằm xung quanh để kiểm tra điều này, nhưng điều này sẽ cung cấp cho bạn một số ý tưởng. Tuy nhiên, hầu hết chúng là những thứ khá cơ bản (chuỗi OR operator và Chứa lời gọi phương thức) nên nó không gây ra vấn đề khi truy vấn dịch sang SQL.
Trước tiên tôi tạo ra một chức năng tùy chỉnh mà sẽ xây dựng ngữ của tôi:
Func<string, Func<DataItem, bool>> buildKeywordPredicate =
keyword =>
x => x.Title.Contains(keyword)
|| x.Contents.Contains(keyword);
Đây là một chức năng mà phải mất một từ khóa chuỗi đơn và sau đó trở về một chức năng mà phải mất một DataItem và kiểm tra nó chống lại các từ khóa.
Về cơ bản, nếu bạn chuyển vào "Ngăn xếp", bạn sẽ nhận được vị từ: x => x.Title.Contains("Stack") || x.Contents.Contains("Stack")
.
Tiếp theo, vì có nhiều từ khóa càng tốt và bạn cần phải xích nó với một hoạt động OR, tôi tạo ra một chức năng helper để chuỗi 2 vị cùng với một HOẶC
Func<Func<DataItem,bool>, Func<DataItem, bool>, Func<DataItem, bool>> buildOrPredicate =
(pred1, pred2) =>
x => pred1(x) || pred2(x);
chức năng này có 2 vị từ và sau đó tham gia chúng với một hoạt động OR.
Có những 2 chức năng, sau đó tôi có thể xây dựng của tôi, nơi vị như thế này:
foreach (var word in keywords) {
filter = filter == null
? buildKeywordPredicate(word)
: buildOrPredicate(filter, buildKeywordPredicate(word));
}
Dòng đầu tiên bên trong vòng lặp cơ bản kiểm tra nếu bộ lọc là null. Nếu có, thì chúng tôi muốn có một bộ lọc từ khóa đơn giản được xây dựng cho chúng tôi.
Khác nếu bộ lọc không rỗng, chúng tôi cần chuỗi các bộ lọc hiện có bằng thao tác OR, vì vậy chúng tôi vượt qua bộ lọc hiện tại và bộ lọc từ khóa mới để xây dựngOrPredicate để thực hiện điều đó.
Và rồi bây giờ chúng tôi có thể tạo ra các phần WHERE của truy vấn:
var result = data.Where(filter);
Đi qua trong vị ngữ phức tạp chúng ta vừa xây dựng.
Tôi không biết điều này sẽ khác với việc sử dụng PredicateBuilder hay không nhưng vì chúng tôi trì hoãn việc dịch truy vấn sang công cụ LINQ-to-SQL, nên không có bất kỳ vấn đề gì.
Nhưng như tôi đã nói, tôi không thử nghiệm nó dựa trên bối cảnh dữ liệu thực, vì vậy nếu có bất kỳ vấn đề nào bạn có thể viết trong phần bình luận.
Dưới đây là các ứng dụng giao diện điều khiển mà tôi xây dựng để kiểm tra: http://pastebin.com/feb8cc1e
Hope this helps!
EDIT: Đối với một phiên bản chung chung hơn và tái sử dụng trong đó bao gồm việc sử dụng đúng cách các cây Expression trong LINQ, hãy kiểm tra bài viết trên blog Thomas Petricek của: http://tomasp.net/articles/dynamic-linq-queries.aspx
này unfortunatelly sẽ chỉ làm việc cho các chức năng. Để thực hiện công việc này với cây biểu thức, bạn cần sử dụng một mẹo như sau: http://tomasp.net/articles/dynamic-linq-queries.aspx –
Đó là một số thành tích bạn đã làm ở đó! và nhiều hơn nữa awesomeness ... Dù sao, tôi là một thuê bao của blog của bạn bây giờ :-) – chakrit
Cảm ơn, điều này đã làm việc. http://tomasp.net/articles/dynamic-linq-queries.aspx - Tomas Petricek – Amir