为什么此筛选器适用于 List<T> 但不适用于 IQueryable<T>?
Why does this filter work on a List<T> but not on an IQueryable<T>?
我需要创建一个扩展方法来根据验证规则列表 List<<IRule>, bool>
过滤集合 List<TSource>
。
但是我得到一个错误 VisitSubQueryExpression method is not implemented
而我没有 see/can 找不到问题的原因。
这是我的扩展方法:
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
}
扩展方法调用示例[=46=]
//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 实例,名称 属性 为 Null 或 Whitespace
我的扩展方法有什么问题?这个 "VisitSubQueryExpression method is not implemented" 错误是什么意思?
如果我将其更改为 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();
}
List<T>
没有实现 IQueryable<T>
,所以你不能调用在 IQueryable<T>
.
上定义的扩展方法
您的 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>
实现了 IEnumerable<T>
但反之则不然。 List<T>
没有实现 IQueryable<T>
.
这是List公开的接口列表:
由于 IQueryable
和 IList
都继承自 IEnumerable<T>
,您可以使用它并调用 .AsQueryable
来转换这两种情况。
我需要创建一个扩展方法来根据验证规则列表 List<<IRule>, bool>
过滤集合 List<TSource>
。
但是我得到一个错误 VisitSubQueryExpression method is not implemented
而我没有 see/can 找不到问题的原因。
这是我的扩展方法:
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
}
扩展方法调用示例[=46=]
//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 实例,名称 属性 为 Null 或 Whitespace
我的扩展方法有什么问题?这个 "VisitSubQueryExpression method is not implemented" 错误是什么意思?
如果我将其更改为 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();
}
List<T>
没有实现 IQueryable<T>
,所以你不能调用在 IQueryable<T>
.
您的 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>
实现了 IEnumerable<T>
但反之则不然。 List<T>
没有实现 IQueryable<T>
.
这是List公开的接口列表:
由于 IQueryable
和 IList
都继承自 IEnumerable<T>
,您可以使用它并调用 .AsQueryable
来转换这两种情况。