使用表达式访问者来检测对string.IsNullOrWhiteSpace的引用,并将其分解为更简单的表达式(x == null || x.Trim() == string.Empty)
。
因此,下面是扩展的访问者和使用它的扩展方法。它不需要特殊的配置即可使用,只需调用WhereEx而不是Where。
public class QueryVisitor: ExpressionVisitor
{
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.IsStatic && node.Method.Name == "IsNullOrWhiteSpace" && node.Method.DeclaringType.IsAssignableFrom(typeof(string)))
{
//!(b.Diameter == null || b.Diameter.Trim() == string.Empty)
var arg = node.Arguments[0];
var argTrim = Expression.Call(arg, typeof (string).GetMethod("Trim", Type.EmptyTypes));
var exp = Expression.MakeBinary(ExpressionType.Or,
Expression.MakeBinary(ExpressionType.Equal, arg, Expression.Constant(null, arg.Type)),
Expression.MakeBinary(ExpressionType.Equal, argTrim, Expression.Constant(string.Empty, arg.Type))
);
return exp;
}
return base.VisitMethodCall(node);
}
}
public static class EfQueryableExtensions
{
public static IQueryable<T> WhereEx<T>(this IQueryable<T> queryable, Expression<Func<T, bool>> where)
{
var visitor = new QueryVisitor();
return queryable.Where(visitor.VisitAndConvert(where, "WhereEx"));
}
}
因此,如果您运行myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
它,它将!(c.Name == null || x.Trim() == "")
在传递给任何内容(对SQL /实体的Linq)并转换为sql之前将其转换为。
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;