简体   繁体   English

为什么此过滤器对列表起作用 <T> 但不在IQueryable上 <T> ?

[英]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. 由于IQueryableIList都继承自IEnumerable<T>您可以使用它并对其调用.AsQueryable来转换两种情况。

List<T>不实现IQueryable<T> ,因此您不能在IQueryable<T>上定义的扩展方法上调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM