【发布时间】:2018-06-23 16:29:36
【问题描述】:
对于给定的搜索标签过滤器,预期的结果是一个表达式,表示在给定的标签 ID 列表中具有所有标签的实体。
一个 Lambda 可能将其表示为:
class Tag
{
public long TagId { get; set; }
}
class Taggable
{
ICollection<Tag> Tags { get; set; }
}
...
IEnumerable<long> searchTags = new List<long>() { 1, 2, 3 };
Func<Taggable, bool> filter = taggable => searchTags.All(qtag => taggable.Tags.Any(tag => tag.TagId == qtag));
尝试将其表示为表达式树失败:
var tagParam = Expression.Parameter(typeof(Tag), "tag");
var taggableParam = Expression.Parameter(typeof(Taggable), "taggable");
MemberExpression tagsProperty = Expression.Property(taggableParam, "Tags");
ConstantExpression searchTagsConstant = Expression.Constant(searchTags);
var containsCall = Expression.Call(
typeof(Enumerable), "Contains",
new[] { typeof(long) },
searchTagsConstant,
Expression.Property(tagParam, "TagID")
);
var anyCall = Expression.Call(
typeof(Enumerable), "Any",
new[] { typeof(Tag) },
tagsProperty,
Expression.Lambda(containsCall, tagParam)
);
// FAILS HERE
var allCall = Expression.Call(
typeof(Enumerable), "All",
new[] { typeof(long) },
searchTagsConstant,
anyCall
);
类型“System.Linq.Enumerable”上的通用方法“All”不兼容 使用提供的类型参数和参数。没有类型参数 如果方法是非泛型的,则应提供。
人们认为它会起作用,因为 Enumerable.All<TSource, Func<TSource, bool>> 应该满足 searchTagsConstant 和 anyCall 的要求?
【问题讨论】:
-
您能否修复您的代码示例以定义
taggable在您的行Expression.Property(taggable, "Tags");中是什么? -
@Stand__Sure 这个答案只针对
Any。问题是关于 All with Any。 -
两者都是静态扩展。该方法应该适用于两者
标签: c# linq expression-trees