Làm cách nào để xây dựng một cây biểu thức khi các phần của biểu thức được chuyển làm đối số?Kết hợp các biểu thức trong cây biểu thức
Ví dụ: những gì nếu tôi muốn tạo ra cây biểu hiện như thế này:
IQueryable<LxUser> test1(IQueryable<LxUser> query, string foo, string bar)
{
query=query.Where(x => x.Foo.StartsWith(foo));
return query.Where(x => x.Bar.StartsWith(bar));
}
nhưng bằng cách tạo ra chúng gián tiếp:
IQueryable<LxUser> test2(IQueryable<LxUser> query, string foo, string bar)
{
query=testAdd(query, x => x.Foo, foo);
return testAdd(query, x => x.Bar, bar);
}
IQueryable<T> testAdd<T>(IQueryable<T> query,
Expression<Func<T, string>> select, string find)
{
// how can I combine the select expression with StartsWith?
return query.Where(x => select(x) .. y => y.StartsWith(find));
}
Kết quả:
Trong khi các mẫu không có ý nghĩa nhiều (xin lỗi nhưng tôi đã cố giữ nó đơn giản), đây là kết quả (cảm ơn Quartermeister).
Nó có thể được sử dụng với LINQ-to-Sql để tìm kiếm chuỗi bắt đầu bằng hoặc bằng findText.
public static IQueryable<T> WhereLikeOrExact<T>(IQueryable<T> query,
Expression<Func<T, string>> selectField, string findText)
{
Expression<Func<string, bool>> find;
if (string.IsNullOrEmpty(findText) || findText=="*") return query;
if (findText.EndsWith("*"))
find=x => x.StartsWith(findText.Substring(0, findText.Length-1));
else
find=x => x==findText;
var p=Expression.Parameter(typeof(T), null);
var xpr=Expression.Invoke(find, Expression.Invoke(selectField, p));
return query.Where(Expression.Lambda<Func<T, bool>>(xpr, p));
}
ví dụ:
var query=context.User;
query=WhereLikeOrExact(query, x => x.FirstName, find.FirstName);
query=WhereLikeOrExact(query, x => x.LastName, find.LastName);
Cảm ơn, câu trả lời đầu tiên của bạn chính xác là những gì tôi đang tìm kiếm! – laktak
Một lưu ý quan trọng ở đây là sẽ làm việc với LINQ2SQL và LINQ2Entities, nhưng không với EF-EF, vì lý do nổi tiếng nhất, không thực hiện 'Expression.Invoke'. – nicodemus13