2017-07-25 83 views
1

假設下面的預過濾的IQueryable覆蓋where子句:如何刪除或現有的IQueryable

var query = items.Where(i => i.PropertyName == "Some property"); 

從第三方庫的到來,是否有可能要麼完全刪除Where子句,或將其替換爲:

.Where(i => i.PropertyName == null || i.PropertyName == "Some property") 

我見過提到能夠在動態重寫IQueryable。這種方法會有什麼缺點嗎?我該怎麼去做呢?有沒有更好的辦法?

更新

我已經成功地湊齊使用ExpressionVisitor東西的建議由伊萬:

public class WhereRemoveVisitor : ExpressionVisitor 
{ 
    protected override Expression VisitMethodCall(MethodCallExpression node) 
    { 
     if (node.Method.Name == "Where" && node.Method.DeclaringType == typeof(Queryable)) 
      return node.Arguments[0]; 
     else 
      return base.VisitMethodCall(node); 
    } 
} 

和:

public static class IQueryableExtensions 
{ 
    public static IQueryable<T> RemoveWhere<T>(this IQueryable<T> expression) 
    { 
     return Expression.Lambda<IQueryable<T>>(new WhereRemoveVisitor().Visit(expression.Expression)).Compile(); 
    } 
} 

這枚編譯罰款,它會拋出「 Lambda類型參數必須從擴展方法中的System.Delegate派生「。

+1

只要你知道你需要,你可以使用自定義到底是什麼'ExpressionVisitor '查找/替換/刪除部分查詢表達式樹。 –

回答

1

我已經成功地放在一起使用ExpressionVisitor東西的建議由伊萬:

public class WhereRemoveVisitor : ExpressionVisitor 
{ 
    protected override Expression VisitMethodCall(MethodCallExpression node) 
    { 
     if (node.Method.Name == "Where" && node.Method.DeclaringType == typeof(Queryable)) 
      return node.Arguments[0]; 
     else 
      return base.VisitMethodCall(node); 
    } 
} 

和:

public static class IQueryableExtensions 
{ 
    public static IQueryable<T> RemoveWhere<T>(this IQueryable<T> expression) 
    { 
     var delExpr = Expression.Lambda<Func<IQueryable<T>>>(new WhereRemoveVisitor().Visit(expression.Expression)).Compile(); 
     return delExpr(); 
    } 
} 
+1

關閉。但不是編譯和調用,只需使用'return query.Provider.CreateQuery (new WhereRemoveVisitor()。Visit(query.Expression));':) –

+1

謝謝@IvanStoev – LukeP

相關問題