2010-03-17 3 views
7

Có ai có một ý tưởng làm thế nào để tạo một hàm Chứa (string) sử dụng LINQ Expressions, hoặc thậm chí tạo ra một vị ngữ để thực hiện điều nàyLINQ Expression <Func <T, bool>> equavalent của Chứa()

public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, 
     Expression<Func<T, bool>> expr2) 
{ 
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>()); 
    return Expression.Lambda<Func<T, bool>> 
       (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters); 
} 

Một cái gì đó mô phỏng này sẽ là lý tưởng?

+2

Bắt đầu ngoại trừ một số câu trả lời đầu tiên, chẳng hạn như http://stackoverflow.com/questions/1648270/how-to-determine-what-happens-behind-the-scene-in-net/1648306#1648306 và điều này http://stackoverflow.com/questions/2331927/linq-to-xml-replace-child-nodes-but-keep-state/2332087#2332087. – Steven

+0

Ở đây một số khác: http://stackoverflow.com/questions/1270783/how-to-combine-two-expressions-result-exp1exp2 – Kamarey

+0

Thx để chỉ ra rằng, liên quan đến –

Trả lời

6
public static Expression<Func<string, bool>> StringContains(string subString) 
{ 
    MethodInfo contains = typeof(string).GetMethod("Contains"); 
    ParameterExpression param = Expression.Parameter(typeof(string), "s"); 
    return Expression.Call(param, contains, Expression.Constant(subString, typeof(string))); 
} 

... 

// s => s.Contains("hello") 
Expression<Func<string, bool>> predicate = StringContains("hello"); 
+0

Bí quyết, thx –

+0

Chỉ cần cung cấp cho một số rõ ràng, giải pháp này đã đề cập ở trên sẽ không hoạt động nếu bạn sử dụng nó trực tiếp, tôi chỉ sử dụng một số nội dung như MethodInfo và ParameterExpression. –

1

Tôi sử dụng thứ gì đó tương tự, nơi tôi thêm bộ lọc vào truy vấn.

public static Expression<Func<TypeOfParent, bool>> PropertyStartsWith<TypeOfParent, TypeOfPropery>(PropertyInfo property, TypeOfPropery value) 
{ 
    var parent = Expression.Parameter(typeof(TypeOfParent)); 
    MethodInfo method = typeof(string).GetMethod("StartsWith",new Type[] { typeof(TypeOfPropery) }); 
    var expressionBody = Expression.Call(Expression.Property(parent, property), method, Expression.Constant(value)); 
    return Expression.Lambda<Func<TypeOfParent, bool>>(expressionBody, parent); 
} 

Cách sử dụng, để áp dụng bộ lọc với thuộc tính có tên khớp với Khóa và sử dụng giá trị được cung cấp, Giá trị.

public static IQueryable<T> ApplyParameters<T>(this IQueryable<T> query, List<GridParameter> gridParameters) 
{ 

    // Foreach Parameter in List 
    // If Filter Operation is StartsWith 
    var propertyInfo = typeof(T).GetProperty(parameter.Key); 
    query = query.Where(PropertyStartsWith<T, string>(propertyInfo, parameter.Value)); 
} 

Và vâng, phương pháp này hoạt động bằng bao gồm:

 public static Expression<Func<TypeOfParent, bool>> PropertyContains<TypeOfParent, TypeOfPropery>(PropertyInfo property, TypeOfPropery value) 
    { 
     var parent = Expression.Parameter(typeof(TypeOfParent)); 
     MethodInfo method = typeof(string).GetMethod("Contains", new Type[] { typeof(TypeOfPropery) }); 
     var expressionBody = Expression.Call(Expression.Property(parent, property), method, Expression.Constant(value)); 
     return Expression.Lambda<Func<TypeOfParent, bool>>(expressionBody, parent); 
    } 

Bởi có những 2 ví dụ, bạn có thể dễ dàng hiểu thế nào chúng ta có thể gọi phương pháp khác nhau bằng tên.