Có một cách để chuẩn bị các truy vấn năng động và điều kiện, và cũng có thể sử dụng chức năng để xây dựng các bộ phận của chúng. Cú pháp cũng có thể đọc được, điều này sẽ làm cho phần "đơn giản" của câu hỏi. Có thể thông qua kết hợp biểu thức LINQ. Có một số bài viết về cách thức này có thể được thực hiện, nhưng tôi nghĩ rằng tôi đã đưa ra một cách tiếp cận mới. Ít nhất tôi không tìm thấy nó trên web.
Để tiếp tục, bạn cần thư viện gồm 3 hàm đơn giản. Họ sử dụng System.Linq.Expressions.ExpressionVisitor
để tự động sửa đổi các biểu thức. Tính năng chính là hợp nhất các tham số bên trong biểu thức, sao cho 2 tham số có cùng tên được tạo giống hệt nhau (UnifyParametersByName
). Phần còn lại sẽ thay thế một tham số có tên với biểu thức đã cho (ReplacePar
) và phương thức trợ giúp (NewExpr
). Thư viện có sẵn với giấy phép MIT trên github: LinqExprHelper, nhưng bạn có thể nhanh chóng viết một cái gì đó của riêng bạn.
Trước tiên, bạn xác định một số phương pháp, sau này có thể được sử dụng trong việc tạo truy vấn động.
public class Store
{
...
public static Expression<Func<Store, bool>>
SafeSearchName(string sWhat)
{
return LinqExprHelper.NewExpr(
(Store s) => s.Name != null && s.Name.ToLower().Contains(sWhat)
);
}
public static Expression<Func<Store, bool>>
SafeSearchDesc(string sWhat)
{
return LinqExprHelper.NewExpr(
(Store s) => s.Description != null && s.Description.ToLower().Contains(sWhat)
);
}
}
Sau đó, bạn truy vấn theo cách này:
// Define a master condition, using named parameters.
var masterExpr = LinqExprHelper.NewExpr(
(Store s, bool bSearchName, bool bSearchDesc)
=> (bSearchName && bSearchDesc));
// Replace stub parameters with some real conditions.
var combExpr = masterExpr
.ReplacePar("bSearchName", Store.SafeSearchName("b").Body)
.ReplacePar("bSearchDesc", Store.SafeSearchDesc("p").Body);
// Sometimes you may skip a condition using this syntax:
//.ReplacePar("bSearchDesc", Expression.Constant(true));
// It's interesting to see how the final expression looks like.
Console.WriteLine("expr: " + combExpr);
// Execute the query using combined expression.
db.Stores
.Where((Expression<Func<Store, bool>>)combExpr)
.ToList().ForEach(i => { Console.WriteLine(i.Name + ", " + i.Description); });
Tôi không sử dụng này trong sản xuất, nhưng một số xét nghiệm đơn giản được thông qua. Tôi không thấy bất kỳ giới hạn nào trong việc kết hợp các truy vấn theo cách này.Nếu chúng ta cần thêm thông số, chúng ta có thể nối thêm mức kết hợp. Ưu điểm của phương thức này là bạn có thể sử dụng các biểu thức lambda nội tuyến, rất hay để đọc, cùng với việc tạo và tạo thành biểu thức năng động, rất có khả năng.
Sau khi tất cả có "đơn giản" không? Nếu bạn xem xét cú pháp phương pháp của Linq đơn giản, thì điều này gần như là đơn giản. Nó không cho phép bạn tạo các hàm LINQ tùy chỉnh, nhưng cho bạn khả năng so sánh.
Loại đối chiếu trên cơ sở dữ liệu của bạn là gì? – Brannon