Gần đây, tôi đã gặp phải sự cố khi tạo động các biểu thức LINQ trong thời gian chạy. Hầu hết các ví dụ tôi tìm thấy đối phó với các nhiệm vụ khá đơn giản chỉ cần so sánh một tài sản của một thực thể cơ sở dữ liệu nhất định với một tham số duy nhất. Cũng giống như vậy:Tạo biểu thức LINQ có chứa truy vấn phụ
Session.Query.Where(m => m.Name.Contains("test"))
nào cũng có thể đạt được với một cách tiếp cận chung chung hơn như thế này:
var item = Expression.Parameter(typeof (MyClass), "item");
var property = Expression.Property(item, "Name");
var containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var searchExpression = Expression.Constant(searchString, typeof(string));
var containsMethodExpression = Expression.Call(property, containsMethod, searchExpression);
var lambda = Expression.Lambda<Func<MyClass, bool>>(containsMethodExpression, item);
query = query.Where(lambda);
Tuy nhiên, đôi khi nhiệm vụ có phần phức tạp hơn và ai muốn đạt được một cái gì đó như sau:
Session.Query.Where(m => m.SpecialProperty.Any(f => f.Name.Contains("test")));
Trường hợp "SpecialProperty" thuộc loại Danh sách <> và thuộc tính "Tên" thuộc loại chuỗi.
Có thể xây dựng một biểu thức LINQ như thế này một cách năng động và làm cách nào để đạt được điều này? Có bất kỳ mối lo ngại về hiệu suất nào liên quan đến cách tiếp cận này không?