Заменено (я думаю) лучшим ответом.
Вы можете написать метод для генерации правильного Expression
для представления очищенного значения с использованием ExpressionVisitor
. Самый простой способ его использования - написать новую версию Where
, чтобы вывод типа работал для вас.
public static class IQueryableExt {
// body only for LINQ to Objects use
public static string RemoveAll(this string src, string removeChars) => removeChars.Aggregate(src, (ans,ch) => ans.Replace(ch.ToString(), ""));
private static Expression CleanUp(this Expression dbFn, string charsToRemove) {
var toCharE = Expression.Constant(String.Empty);
var replaceMI = typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) });
var methodBody = dbFn;
foreach (var ch in charsToRemove)
methodBody = Expression.Call(methodBody, replaceMI, Expression.Constant(ch.ToString()), toCharE);
return methodBody;
}
/// <summary>
/// ExpressionVisitor to expand x.RemoveAll("x..z") to x.Replace("x","")...Replace("z","") in
/// an Expression.
/// </summary>
private class RemoveAllVisitor : ExpressionVisitor {
public override Expression Visit(Expression node) {
if (node?.NodeType == ExpressionType.Call) {
var callnode = (MethodCallExpression)node;
if (callnode.Method.Name == "RemoveAll" && callnode.Method.DeclaringType == typeof(IQueryableExt))
if (callnode.Arguments[1] is ConstantExpression ce && ce.Type == typeof(string))
return callnode.Arguments[0].CleanUp(ce.Value.ToString());
}
return base.Visit(node);
}
}
private static T ExpandRemoveAll<T>(this T orig) where T : Expression => (T)new RemoveAllVisitor().Visit(orig);
public static IQueryable<T> WhereRemoveAll<T>(this IQueryable<T> src, Expression<Func<T, bool>> predFn) => src.Where(predFn.ExpandRemoveAll());
}
При наличии кода расширения использовать его относительно просто:
var p_name = "michaelscott";
var result = db.tablename
.WhereRemoveAll(x => x.name.RemoveAll("$ ") == p_name)
.FirstOrDefault();
Более общий подход может использовать что-то вроде подхода LINQKit для изменения запроса и автоматического расширения всех встроенных методов с некоторым атрибутом - я добавил некоторый код, используя этот подход, в CodeReview здесь .