我需要创建一个扩展方法,根据验证规则List<TSource>
列表过滤集合List<<IRule>, bool>
。
但是我收到错误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 IQueryable<TSource>
替换为this List<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();
}
答案 0 :(得分:2)
您的rule.RulePassed
无法由您的IQueryable提供商翻译。
public static List<TSource> ValidItems<TSource>(this IQueryable<TSource> source,
List<IValidationRule<TSource>> validationRules)
{
var result = new List<TSource>();
foreach (var testableItem in source)
{
if (validationRules.All(rule => rule.RulePassed(testableItem))
{
result.Add(testableItem);
}
}
return result;
}
答案 1 :(得分:1)
IQueryable<T>
实现IEnumerable<T>
但反之亦然。 List<T>
未实现IQueryable<T>
。
这是List公开的接口列表:
由于IQueryable
和IList
都来自IEnumerable<T>
,您可以使用它并在其上调用.AsQueryable
来转换这两种情况。
答案 2 :(得分:0)
List<T>
未实现IQueryable<T>
,因此您无法在IQueryable<T>
上调用其上的扩展方法。