c# - 自定义 IQueryProvider 中的 ArgumentNullException
问题描述
首先了解我为什么尝试创建自定义的一些背景IQueryProvider
:
我正在为支持IQueryable
. 我不想使用 OData 客户端代码生成器(因为我不想在更改服务器时更新客户端或创建新客户端)。我有一个基于默认 Web API 调用的实现WebClient
,我想将它重用于 OData。我的服务已经支持 OData 并且运行良好。在客户端,我现在需要一个IQueryable
用于将其分配给 DevExpress' ODataInstantFeedbackSource
。
我的问题是我需要执行 HTTP-Request 来获取IQueryable
. 这会导致 OData 查询没有任何限制,从而导致加载大量数据。因此,我的想法是创建某种“可查询的委托”,Func
它在其构造函数中接受委托,它定义了对 Web API 的调用,还可以处理表达式树。
我对该解决方案的尝试(示例项目):
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace IQueryableTest
{
class Program
{
static void Main(string[] args)
{
var x = new FuncQueryable<int>((expr) =>
{
return new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }
.AsQueryable()
.Provider
.CreateQuery<int>(expr);
});
var y = x.Where(i => i % 2 == 0);
var z = y.ToList();
}
}
public class FuncQueryable<T> : IOrderedQueryable<T>
{
public FuncQueryable(Func<Expression, IQueryable<T>> source)
{
Provider = new ActionQueryProvider<T>(source);
}
public FuncQueryable(IQueryProvider provider, Expression expression)
{
Provider = provider;
Expression = expression;
}
public Expression Expression { get; set; }
public Type ElementType => typeof(T);
public IQueryProvider Provider { private set; get; }
public IEnumerator<T> GetEnumerator()
{
return (Provider.Execute<IEnumerable<T>>(Expression)).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return (Provider.Execute<IEnumerable>(Expression)).GetEnumerator();
}
}
public class ActionQueryProvider<T> : IQueryProvider
{
private readonly Func<Expression, IQueryable<T>> _source;
public ActionQueryProvider(Func<Expression, IQueryable<T>> source)
{
_source = source;
}
public IQueryable CreateQuery(Expression expression)
{
return new FuncQueryable<T>(this, expression);
}
public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
{
return new FuncQueryable<TElement>(this, expression);
}
public object Execute(Expression expression)
{
return _source.Invoke(expression);
}
public TResult Execute<TResult>(Expression expression)
{
return (TResult)Execute(expression);
}
}
}
我得到以下异常:
Der Wert darf nicht NULL sein. (ArgumentNullException)
Parametername: arguments
bei System.Linq.Expressions.Expression.RequiresCanRead(Expression expression, String paramName)
bei System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
bei System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments)
bei System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
bei System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)
bei IQueryableTest.Program.Main(String[] args)
排队var y = x.Where(i => i % 2 == 0);
。
解决方案
推荐阅读
- python - 错误:(gcloud.beta.ai-platform.versions.create)参数版本:必须指定
- javascript - JavaScript - 变量的数学运算
- javascript - Reactjs 中的 setState 不是函数
- python - 为什么我的 python 没有正确安装,即使我没有错误?
- javascript - 在输入的检查状态下更改标签背景
- intellij-idea - 如何告诉 intellij 在失败的命令上恢复宏执行?
- javascript - 将对象数组分解为二维数组
- node.js - 变量赋值
- vue.js - 使用 vue-ci-service 创建新变量,如 `BASE_URL` 以在 index.html 中使用
- sql-server - 使用案例语句时计算分组计数