2010-12-29 53 views
7

Hiện nay, tôi có phương pháp này để so sánh hai sốLàm thế nào để tạo ra một cây Expression để làm tương tự như "StartsWith"

Private Function ETForGreaterThan(ByVal query As IQueryable(Of T), ByVal propertyValue As Object, ByVal propertyInfo As PropertyInfo) As IQueryable(Of T) 

    Dim e As ParameterExpression = Expression.Parameter(GetType(T), "e") 
    Dim m As MemberExpression = Expression.MakeMemberAccess(e, propertyInfo) 
    Dim c As ConstantExpression = Expression.Constant(propertyValue, propertyValue.GetType()) 
    Dim b As BinaryExpression = Expression.GreaterThan(m, c) 
    Dim lambda As Expression(Of Func(Of T, Boolean)) = Expression.Lambda(Of Func(Of T, Boolean))(b, e) 
    Return query.Where(lambda) 

End Function 

Nó hoạt động tốt và được tiêu thụ theo cách này

query = ETForGreaterThan(query, Value, propertyInfo) 

Như bạn có thể thấy, tôi cung cấp cho nó một bộ sưu tập IQueryable và nó thêm một mệnh đề where vào nó, dựa trên một thuộc tính và một giá trị. Y có thể xây dựng Lessthan, LessOrEqualThan vv tương đương với System.Linq.Expressions.Expression có các toán tử này được xác định trước.

¿Làm cách nào để tôi có thể chuyển đổi mã này để thực hiện tương tự với chuỗi? System.Linq.Expressions.Expression không cho tôi một toán tử được định nghĩa trước như "contains" hoặc "startwith" và tôi thực sự là noob với cây Expression.

Xin cảm ơn, và vui lòng Đăng câu trả lời của bạn bằng C#/VB. Chọn cái khiến bạn cảm thấy bối rối hơn.

Trả lời

17
using System; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 

namespace WindowsFormsApplication1 
{ 
    static class Program 
    { 
     [STAThread] 
     static void Main() 
     { 
      using (var context = new NorthwindEntities()) 
      { 
       PropertyInfo propertyInfo = typeof(Customer).GetProperty("CustomerID"); 

       IQueryable<Customer> query = context.Customers; 
       query = ETForStartsWith<Customer>(query, "A", propertyInfo); 
       var list = query.ToList(); 
      } 
     } 

     static IQueryable<T> ETForStartsWith<T>(IQueryable<T> query, string propertyValue, PropertyInfo propertyInfo) 
     { 
      ParameterExpression e = Expression.Parameter(typeof(T), "e"); 
      MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo); 
      ConstantExpression c = Expression.Constant(propertyValue, typeof(string)); 
      MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }); 
      Expression call = Expression.Call(m, mi, c); 

      Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(call, e); 
      return query.Where(lambda); 
     } 
    } 
} 
+0

Đã kiểm tra và làm việc lại. Hai lần ít hơn 24h. Tom, có bất kỳ posibility để mua một ly bia cho bạn? : D Cảm ơn, thực sự. – Jonathan

+0

Tom - bạn là một anh hùng – whiteshooz

4

Nó không phải là toán tử, mà là phương thức, vì vậy bạn có thể gọi nó bằng Expression.Call(), trong đó tham số methodinfo sẽ là typeof (string) .GetMethod ("StartsWith").

+0

Tôi đang đọc về nó, nhưng trước đây tôi không sử dụng cây biểu thức. ¿Bạn có thể cho tôi một ví dụ được không? – Jonathan

Các vấn đề liên quan