c# - 将 IEnumerable 动态转换为 IQueryable 或使用 LINQ 表达式动态调用 AsQueryable

标签 c# linq dynamic

我正在动态创建 LINQ 查询,到目前为止一切正常。

但我被困在了我认为不会的地方。在构建该查询的某个时刻,我需要访问实体的 EnityCollection。像这样:

Expression collection = Expression.Property(entity, typeof(EntityType).GetProperty("CollectionOfRelatedEntities"));

然后,我将对该集合调用“Where”LINQ 方法:

MethodCallExpression AfterWhere = Expression.Call(
                        typeof(Queryable),
                        "Where",
                        new Type[] { typeof(RelatedEntity) },
                        collection,
                        Expression.Lambda<Func<RelatedEntity, bool>>(predicate, new ParameterExpression[] { paramOfRelatedEntity }));

通常这会奏效。在这种情况下,它不会因为集合是 IEnumerable 并且我需要它是 IQueryable 才能在“Where”工作。

我试过这个:

Expression.Convert(collection, typeof(IQueryable<RelatedEntity>);

但它说无法转换,因为 EntityCollection 没有实现 IQueryable。

我静态地使用 AsQueryable 来实现我在这里需要的东西,所以我尝试动态地模仿它:

Expression.Call(collection, typeof(EntityCollection<RelatedEntity>).GetMethod("AsQueryable"));

但是我得到空引用异常。我无法通过反射到达它。这个 AsQueryable 方法是扩展方法,它是静态的,在 Queryable 类中定义,所以我尝试了:

Expression.Call(collection, typeof(Queryable).GetMethod("AsQueryable", BindingFlags.Static)); 

相同的结果:“值不能为空”。

我在这里达到了我的极限,我的想法很新鲜。

所以,我问你:

如何将 IEnumerable 动态转换为 IQueryable?

最佳答案

尝试这样获取方法:

var method = typeof(Queryable).GetMethod(
    "AsQueryable",
    BindingFlags.Static | BindingFlags.Public, 
    null, 
    new [] { typeof(IEnumerable<RelatedEntity>)}, 
    null);

然后,您应该能够像这样构建对该方法的调用:

Expression.Call(method, collection);

您的代码存在的问题是 BindingFlags 很难使用。如果您指定任何 BindingFlags(例如 BindingFlags.Static),那么您必须明确说明您是想要 BindingFlags.Public 还是 BindingFlags.NonPublic。

那么第二个问题是有两个 AsQueryable 方法——一个通用的和一个非通用的。提供类型参数数组可以解决这种歧义。

关于c# - 将 IEnumerable 动态转换为 IQueryable 或使用 LINQ 表达式动态调用 AsQueryable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9337125/

相关文章:

c# - 如何从 Silverlight Out-of-Browser 打开弹出窗口?

c# - 响应重定向不起作用

c# - 哪个是使用 LINQ 的更好方法?

c# - TaskFactory.Tasks 中 BlockingCollection.GetConsumingEnumerable() 集合的 Parallel.ForEach 和 foreach 循环

c# - 绑定(bind)到值类型的通用类型参数 - 使它们可以为空

linq - 处理 Azure 表批量更新的可靠且高效的方法

c# - 使用 Linq 和 C#,我怎样才能根据某些条件合并两个列表?

使用 Racket 宏动态定义符号和宏

ios - 动态表格 View 单元格,防止创建自动高度约束

arrays - 给定 "source code"字符串列表,如何创建数组组合字符串?