gpt4 book ai didi

c# - 如何合并两个成员表达式树?

转载 作者:太空狗 更新时间:2023-10-30 00:59:23 24 4
gpt4 key购买 nike

我试图将以下表达式组合成一个表达式:item => item.sub,sub => sub.key 变成 item => item.sub.key。我需要这样做,以便我可以创建一个 OrderBy 方法,该方法将项目选择器单独带到键选择器。这可以使用 OrderBy 上的重载之一并提供一个 IComparer<T> 来完成。 ,但它不会转换为 SQL。

以下是一个方法签名,用于进一步阐明我要实现的目标,以及一个不起作用但应该说明这一点的实现。

    public static IOrderedQueryable<TEntity> OrderBy<TEntity, TSubEntity, TKey>(
this IQueryable<TEntity> source,
Expression<Func<TEntity, TSubEntity>> selectItem,
Expression<Func<TSubEntity, TKey>> selectKey)
where TEntity : class
where TSubEntity : class
{
var parameterItem = Expression.Parameter(typeof(TEntity), "item");
...
some magic
...
var selector = Expression.Lambda(magic, parameterItem);
return (IOrderedQueryable<TEntity>)source.Provider.CreateQuery(
Expression.Call(typeof(Queryable), "OrderBy", new Type[] { source.ElementType, selector.Body.Type },
source.Expression, selector
));
}

这将被称为:

.OrderBy(item => item.Sub, sub => sub.Key)

这可能吗?有没有更好的办法?我想要一个以这种方式工作的 OrderBy 方法的原因是为了支持适用于许多实体的复杂键选择表达式,尽管它们以不同的方式公开。此外,我知道有一种方法可以使用深层属性的 String 表示来执行此操作,但我正在努力保持它的强类型。

最佳答案

由于这是 LINQ-to-SQL,您通常可以使用 Expression.Invoke 来发挥子表达式的作用。我看看能不能举个例子(update: done)。但是请注意,EF 不支持此功能 - 您需要从头开始重建表达式。我有一些代码可以执行此操作,但是它很长...

表达式代码(使用Invoke)非常简单:

var param = Expression.Parameter(typeof(TEntity), "item");
var item = Expression.Invoke(selectItem, param);
var key = Expression.Invoke(selectKey, item);
var lambda = Expression.Lambda<Func<TEntity, TKey>>(key, param);
return source.OrderBy(lambda);

这是 Northwind 上的示例用法:

using(var ctx = new MyDataContext()) {
ctx.Log = Console.Out;
var rows = ctx.Orders.OrderBy(order => order.Customer,
customer => customer.CompanyName).Take(20).ToArray();
}

使用 TSQL(重新格式化以适合):

SELECT TOP (20) [t0].[OrderID], -- snip
FROM [dbo].[Orders] AS [t0]
LEFT OUTER JOIN [dbo].[Customers] AS [t1]
ON [t1].[CustomerID] = [t0].[CustomerID]
ORDER BY [t1].[CompanyName]

关于c# - 如何合并两个成员表达式树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/560039/

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