.net-core - 构造表达式树以调用 IQueryable 集合上的 Any 方法(嵌套查询)
问题描述
我正在尝试构建一个扩展方法来IQueryable
检查导航属性中是否有任何匹配的元素。我在下面的代码之外做的是迭代一个类型的属性并检查该属性是否是使用IModel
.
我在试图弄清楚如何为一对多关系构建表达式树时遇到问题。我想要实现的是类似Entity.Collections.Any(Collection => Collection.Name == 'Filter')
的,然后是主查询的 where 子句。内部子句是在下面的示例之外构建的,但我相信错误发生在到达该表达式之前。
我认为 the 的委托类型Lambda
可能构造错误,因为它没有返回bool
,它正在返回IEnumerable<Collection>
,但如果不是这样,我无法弄清楚它应该如何构造。
我正在尝试遵循Microsoft 文档中的本指南。
试图解决上述问题的代码行:
if (typeof(IEnumerable).IsAssignableFrom(targetType))
{
var targetEntity = targetType.GetGenericArguments().First();
var subArgument = Expression.Parameter(targetEntity, targetEntity.Name);
var delegateType = typeof(Func<,>).MakeGenericType(targetEntity, typeof(bool));
var lambda = Expression.Lambda(delegateType, innerClause, Expression.Parameter(targetEntity));
Expression.Call(
typeof(Queryable),
"Any",
new Type[] { targetEntity },
Expression.Property(argument, property.Name),
lambda
);
}
我在尝试创建Expression.Call
.
Exception thrown: 'System.InvalidOperationException' in System.Linq.Expressions.dll: 'No generic method 'Any' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. '
我还尝试获取 any 方法并调用它:
var anyMethod = typeof(Queryable)
.GetMethods()
.Where(m => m.Name == "Any" && m.IsGenericMethodDefinition)
.Where(m => m.GetParameters().ToList().Count == 2)
.First();
var genericMethod = anyMethod.MakeGenericMethod(entityType);
genericMethod.Invoke(Expression.Property(argument, property.Name), new object[] { innerClause, subArgument });
然后我得到了这个错误:
Exception thrown: 'System.ArgumentException' in System.Private.CoreLib.dll: 'Object of type 'System.Linq.Expressions.MethodCallExpression3' cannot be converted to type 'System.Linq.IQueryable
1[收藏]'.'`
任何帮助是极大的赞赏!
解决方案
好吧,也许这个问题有点不清楚,因为我不知道该怎么问,但是,如果有人偶然发现这个问题,我就是这样解决的:
if (typeof(IEnumerable).IsAssignableFrom(targetType))
{
var targetEntity = targetType.GetGenericArguments().First();
var subArgument = Expression.Parameter(targetEntity, targetEntity.Name);
var anyMethod = typeof(Enumerable)
.GetMethods()
.Where(m => m.Name == "Any" && m.IsGenericMethodDefinition)
.Where(m => m.GetParameters().ToList().Count == 2)
.First();
anyMethod = GetAnyMethod().MakeGenericMethod(targetType);
Expression.Call(anyMethod, Expression.MakeMemberAccess(argument, property), Expression.Lambda(x, subArgument));
}
所以,主要问题是我试图在而不是调用方法Queryable
,Enumerable
因为我是在属性而不是可查询对象上调用方法,所以我应该这样做。
推荐阅读
- java - Javers Spring 在保存到历史记录期间设置特定字段数据
- amazon-ec2 - CodeDeploy allowTraffic 失败,但我的代码仍部署在实例上
- c# - 尝试在实体框架中添加迁移时出现“在程序集中找不到 DbContext”错误
- python-3.x - 我如何从网站“flipkart.com”上抓取评论
- sql - 在将数据批量插入表时从文件中删除引号字符
- javascript - Handlebars 使用模板渲染 html
- php - 在同一个 PHP 函数中创建条件语句
- android - 如何设计 tabitems,而不将它们放在 .xml 文件中
- python - 如何制作具有一定滞后的两个时间序列的相关图
- reactjs - 如何遍历firebase中的所有节点