gpt4 book ai didi

linq - 使用在运行时解析的类型调用 System.Linq.Queryable 方法

转载 作者:行者123 更新时间:2023-12-04 20:22:01 27 4
gpt4 key购买 nike

我正在构建一个基于 LINQ 的查询生成器。

其中一项功能是能够将任意服务器端投影指定为查询定义的一部分。例如:

class CustomerSearch : SearchDefinition<Customer>
{
protected override Expression<Func<Customer, object>> GetProjection()
{
return x => new
{
Name = x.Name,
Agent = x.Agent.Code
Sales = x.Orders.Sum(o => o.Amount)
};
}
}

由于用户必须能够对投影属性(而不是客户属性)进行排序,因此我将表达式重新创建为 Func<Customer,anonymous type>而不是 Func<Customer, object> :
//This is a method on SearchDefinition
IQueryable Transform(IQueryable source)
{
var projection = GetProjection();
var properProjection = Expression.Lambda(projection.Body,
projection.Parameters.Single());

为了返回预计的查询,我希望能够做到这一点(实际上,这在几乎相同的概念证明中起作用):
return Queryable.Select((IQueryable<TRoot>)source, (dynamic)properProjection);

TRoot 是 SearchDefinition 中的类型参数。这导致以下异常:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
The best overloaded method match for
'System.Linq.Queryable.Select<Customer,object>(System.Linq.IQueryable<Customer>,
System.Linq.Expressions.Expression<System.Func<Customer,object>>)'
has some invalid arguments
at CallSite.Target(Closure , CallSite , Type , IQueryable`1 , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet]
(CallSite site, T0 arg0, T1 arg1, T2 arg2)
at SearchDefinition`1.Transform(IQueryable source) in ...

如果仔细观察,它会错误地推断通用参数: Customer,object而不是 Customer,anonymous type ,这是 properProjection 的实际类型表达式(双重检查)

我的解决方法是使用反射。但是对于通用参数,这真是一团糟:
var genericSelectMethod = typeof(Queryable).GetMethods().Single(
x => x.Name == "Select" &&
x.GetParameters()[1].ParameterType.GetGenericArguments()[0]
.GetGenericArguments().Length == 2);
var selectMethod = genericSelectMethod.MakeGenericMethod(source.ElementType,
projectionBody.Type);
return (IQueryable)selectMethod.Invoke(null, new object[]{ source, projection });

有谁知道更好的方法?

更新 : 原因 dynamic失败是匿名类型被定义为 internal .这就是为什么它使用概念验证项目工作的原因,其中所有内容都在同一个程序集中。

我很酷。我仍然想找到一种更简洁的方法来找到正确的 Queryable.Select重载。

最佳答案

修复方法很简单,很伤人:

[assembly: InternalsVisibleTo("My.Search.Lib.Assembly")]

关于linq - 使用在运行时解析的类型调用 System.Linq.Queryable 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5438929/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com