式ビジターを使用してstring.IsNullOrWhiteSpaceへの参照を検出し、それらをより単純な式に分解します(x == null || x.Trim() == string.Empty)
。
以下は拡張ビジターとそれを利用するための拡張メソッドです。特別な設定を使用する必要はなく、Whereの代わりにWhereExを呼び出すだけです。
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() == "")
、何にでも渡される前に変換され(linq to sql / entities)、sqlに変換されます。
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;