如何使用 Expression.Call 将 SelectMany 添加到表达式树

发布于 2024-12-26 03:40:42 字数 748 浏览 0 评论 0原文

如何获得与以下内容相同的结果:

var q = db.TableA.AsQueryable();
var q1 = Queryable.SelectMany(q, a => a.TableB, (a, t) => new { a = a, t = t });
var q2 = Queryable.SelectMany(q1, a=> a.a.TableC, (a, t) = new { a = a, t = t });

通过 Expression.Call 创建表达式树:

MethodCallExpression returnCallExpression = Expression.Call(
     typeof(Queryable),
     "SelectMany",
     new Type[] ??????,
     query.Expression,
     a => a.TableB,
     (a, t) => new { a = a, t = t });

我正在研究 Expression.Call 的其他重载,看看是否可以在不声明类型的情况下实现这一点。

我的问题是 SelectMany 的数量是在运行时确定的,所以我不能只是链接它们。每个 SelectMany 都会更改 IQueryable 的匿名类型,因此我很难在编译时不知道类型。

任何有关如何将 n 个 SelectMany 应用于 IQueryable 的想法都将受到高度赞赏。

How do I achive the same result as:

var q = db.TableA.AsQueryable();
var q1 = Queryable.SelectMany(q, a => a.TableB, (a, t) => new { a = a, t = t });
var q2 = Queryable.SelectMany(q1, a=> a.a.TableC, (a, t) = new { a = a, t = t });

by creating an expression tree via Expression.Call:

MethodCallExpression returnCallExpression = Expression.Call(
     typeof(Queryable),
     "SelectMany",
     new Type[] ??????,
     query.Expression,
     a => a.TableB,
     (a, t) => new { a = a, t = t });

I'm researching the other overloads of Expression.Call to see if this can be achieved without declaring type.

My issue is that the number of SelectManys is determined at run-time so I can't just chain them. And each SelectMany changes the anonymous type of the IQueryable, so I'm having trouble getting around not knowing the type at compile-time.

Any ideas about how to apply n number of SelectMany to an IQueryable are greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

迷爱 2025-01-02 03:40:42

您实际上是否有“可用”的 lambda 表达式,例如 a =>; a.TableB 还是它们也是动态的?

您也许可以使用类似的东西(基于此 SO post):

public Type[] GetSelectManysAnonymousTypes<TSource, TCollection, TResult>(
        IQueryable<TSource> queryable,
        Expression<Func<TSource, IEnumerable<TCollection>>> collectionSelector,
        Expression<Func<TSource, TCollection, TResult>> resultSelector)
{
    return new [] {
        typeof(Expression<Func<TSource, IEnumerable<TCollection>>>),
        typeof(Expression<Func<TSource, TCollection, TResult>>) };
}

或者更复杂一点可以给你返回 Type[]Expression[] 即表达式数组 - 准备调用 Expression.Call()。

我认为你面临的问题是,忘记匿名类型,如果你真的有一个动态的、未知数量的 SelectMany() 链接在一起,你不知道 collectionSelector 参数 lambda 是什么样的。或者我可能会错过一些东西......

Do you actually have the lambda expressions "available" such as a => a.TableB or are they dynamic as well?

You could use something like this perhaps (based on this SO post):

public Type[] GetSelectManysAnonymousTypes<TSource, TCollection, TResult>(
        IQueryable<TSource> queryable,
        Expression<Func<TSource, IEnumerable<TCollection>>> collectionSelector,
        Expression<Func<TSource, TCollection, TResult>> resultSelector)
{
    return new [] {
        typeof(Expression<Func<TSource, IEnumerable<TCollection>>>),
        typeof(Expression<Func<TSource, TCollection, TResult>>) };
}

Or something a bit more complicated could give you back the Type[] together with the Expression[] i.e. array of expressions - ready to call Expression.Call().

I think the problem you are facing though is, forgetting anonymous types, you don't know what the collectionSelector parameter lambda looks like if you really have a dynamic, unknown number of SelectMany()'s chained together. Or I may be missing something...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文