[英]Why does this filter work on a List<T> but not on an IQueryable<T>?
I need to create an extension method that will filter collection List<TSource>
according to a list of validation rules List<<IRule>, bool>
. 我需要创建一个扩展方法,该方法将根据验证规则
List<<IRule>, bool>
的列表过滤集合List<TSource>
List<<IRule>, bool>
。 But I get an error VisitSubQueryExpression method is not implemented
and I don't see/can not find what is the problem cause. 但是我收到一个错误,
VisitSubQueryExpression method is not implemented
并且我看不到/找不到问题的原因。
This is my extension method: 这是我的扩展方法:
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 interface: IRule界面:
public interface IValidationRule<T> //with implementation class ValidationRule<T>
{
Func<T, bool> RulePassed { get; set; }
//... +other code
}
Sample of extension method call 扩展方法调用样本
//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
}
});
this sample should filter listToValidate list and remove all SampleType instances, with Name property that is Null or Whitespace 此示例应过滤listToValidate列表并删除所有SampleType实例,其Name属性为Null或空白
What is wrong with my extension method? 我的扩展方式有什么问题? What does this "VisitSubQueryExpression method is not implemented" error mean?
此“ VisitSubQueryExpression方法未实现”错误是什么意思?
if I change it to be an extension method for List<TSource>
not IQueryable<TSource>
- it works! 如果我将其更改为
List<TSource>
而不是IQueryable<TSource>
的扩展方法-它可以工作! Why? 为什么?
replacing this IQueryable<TSource>
with this List<TSource>
, it works, why? this IQueryable<TSource>
替换this List<TSource>
,它起作用了,为什么? Where
method should work on IQueryable<T>
(inherits from IEnumerable<T>
), shouldn't it? 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();
}
Your rule.RulePassed
cannot be translated by your IQueryable provider. 您的
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;
}
IQueryable<T>
implements IEnumerable<T>
but not vice versa. IQueryable<T>
实现IEnumerable<T>
但反之则不。 And List<T>
doesn't implement IQueryable<T>
. 并且
List<T>
不实现IQueryable<T>
。
This is the list of interfaces exposed by List: 这是List公开的接口的列表:
Since both IQueryable
and IList
inherit from IEnumerable<T>
you could use that and call .AsQueryable
on it to convert both cases. 由于
IQueryable
和IList
都继承自IEnumerable<T>
您可以使用它并对其调用.AsQueryable
来转换两种情况。
List<T>
不实现IQueryable<T>
,因此您不能在IQueryable<T>
上定义的扩展方法上调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.