【发布时间】:2015-03-06 14:02:00
【问题描述】:
我需要创建一个扩展方法,该方法将根据验证规则列表List<<IRule>, bool> 过滤集合List<TSource>。
但是我收到一个错误VisitSubQueryExpression method is not implemented,我看不到/找不到问题原因。
这是我的扩展方法:
public static List<TSource> ValidItems<TSource>(this IQueryable<TSource> source,
List<IValidationRule<TSource>> validationRules)
{
return source.Where(testableItem =>
validationRules.All(rule => rule.RulePassed(testableItem))).ToList();
}
IRule 接口:
public interface IValidationRule<T> //with implementation class ValidationRule<T>
{
Func<T, bool> RulePassed { get; set; }
//... +other code
}
扩展方法调用示例
//initialization of List<SampleType> listToValidate = ...
var validItems = listToValidate.ValidItems(
new List<IValidationRule<SampleType>() {
new ValidationType<SampleType> {
RulePassed = (s) => string.IsNullOrWhiteSpace(SampleType.Name),
//...initalize other ValidationType parameters
}
});
此示例应过滤 listToValidate 列表并删除所有 SampleType 实例,其 Name 属性为 Null 或 Whitespace
我的扩展方法有什么问题?这个“VisitSubQueryExpression 方法未实现”错误是什么意思?
如果我将其更改为 List<TSource> 而不是 IQueryable<TSource> 的扩展方法 - 它可以工作!为什么?
用this List<TSource> 替换this IQueryable<TSource>,它可以工作,为什么? Where 方法应该适用于 IQueryable<T>(继承自 IEnumerable<T>),不是吗?
public static List<TSource> ValidItems<TSource>(this List<TSource> source,
List<IValidationRule<TSource>> validationRules)
{
return source.Where(testableItem =>
validationRules.All(rule => rule.RulePassed(testableItem))).ToList();
}
【问题讨论】:
-
你是否直接在 linq-2-entities 查询中使用它?
-
你为什么使用
IQueryable<T>而不是IEnumerable<T>?如果您想将过滤器表达式转换为数据库可以理解的内容(例如 SQL),则前者很有用。除非您的查询提供程序对IValidationRule有特殊支持(几乎不可能),否则它将无法处理该表达式。 -
@CodesInChaos 我打算在 LinqToExcel 上使用它返回 'ExcelQueryable
',它继承自 'QueryableBase ',所以我想我可以在将结果集合转换为 List 之前进行过滤
标签: c# linq extension-methods