看到很多类似下面的代码
var customrs = MyDataContext.Customers.Where(...);
if (!String.IsNullOrEmpty(input)) {
customers = customers.Where(c => c.Email.Contains(input));
}
我想把它放在一个扩展方法中,在调用 IQueryable 上的 Where 之前检查输入是否有效,以便它可以像这样调用
customers = MyDataContext.Customers.Where(...)
.ContainsText(c => c.Email, input);
我的扩展方法是这样的
public static IQueryable<T> ContainsText<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string text) {
if (String.IsNullOrEmpty(text) {
return source;
}
else {
//do something here
}
}
如何在解析的表达式上调用 Contains()?或者是否有另一种方法返回结果的 IQueryable,其中解析的表达式包含解析的文本?
更新:用于Linq to Sql
最佳答案
tvanfosson构建导致 this answer 的表达式的想法是正确的至 this question .因此,为了完整起见,这里有一个完整的工作解决方案
表达式构建器
public static class ExpressionBuilder {
public static Expression<Func<T, bool>> ContainsText<T>(string propertyName, string text) {
var paramExp = Expression.Parameter(typeof(T), "type");
var propExp = Expression.Property(paramExp, propertyName);
var methodInfo = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var valueExp = Expression.Constant(text, typeof(string));
var methCall = Expression.Call(propExp, methodInfo, valueExp);
return Expression.Lambda<Func<T, bool>>(methCall, paramExp);
}
}
扩展方法
public static class IQueryableExtensions {
public static IQueryable<T> ContainsText<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string text) {
if (source == null) {
throw new ArgumentNullException();
}
if (text.IsNullOrEmpty()) {
return source;
}
string propName = ((MemberExpression)selector.Body).Member.Name;
return source.Where(ExpressionBuilder.ContainsText<T>(propName, text));
}
}
像这样调用
var customers = MyDataContext.Customers.Where(/* some code */)
.ContainsText(c => c.Email, input);
关于c# - 扩展 IQueryable 以返回属性包含字符串的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1688020/