1

我的扩展方法的完整定义首先出现。

static IQueryable<TResult> WithTicketNumbers<T, TResult>(
    this IQueryable<T> q,
    Expression<Func<T, Ticket>> ticketSelector,
    Expression<Func<T, string, TResult>> resultSelector,
    int digitsCount)

我有这个IQueryable<T> q序列,这是扩展的目标。

q此方法通过以下方式获取票证ticketSelector

var tickets = q.Select(ticketSelector);

接下来,也是该方法的主要目标,是string从类中获取一些 -linq-supported-infoTicket并将两者Ticketstringinfo 投影到序列旁边:

var tickets2 = tickets.Select(W => new { Ticket = W, Info = W.Name + "123"});

最后,我希望我的方法返回一个IQueryable将选择用户想要的内容resultSelector。这个结果选择器同时选择票证和信息参数,并产生用户希望它产生的结果。我有点坚持Expression上课来创造适当的表达。

到目前为止,我得到了我的两个参数:

ParameterExpression tParameter = Expression.Parameter(typeof(T));
ParameterExpression stringParameter = Expression.Parameter(typeof(string));

另外,我认为,最终的 lambda:

Expression<Func<T, string, TResult>> lambda =
    Expression.Lambda<Func<T, string, TResult>>
    (/* ? */, tParameter, stringParameter);

但是,我无法弄清楚身体。

我可以Expression.Property通过反射获得两个属性TicketInfo,但是需要一个类型,并且我在那里有匿名类型,在tickets2.

接下来,(我猜)我需要在lambda内部使用它tickets2来生成方法 result IQueryable<TResult>

那么我应该如何构建最终表达式呢?

4

2 回答 2

0

我不确定你想要什么 - 但这至少可以帮助你开始(也检查其他答案,建议 - 即dynamic linq
(我仍然建议你使用适当的工具 - http://nuget .org/packages/DynamicLINQ/ )

这是我之前做过的一篇文章(更多的是练习):
Converting List<string> to EntityFramework column/field list

它所做的是基于字符串构造表达式 - 对于Select. 你可以像...一样使用它

public static IEnumerable<object> 
    SelectAsEnumerable(this IQueryable entitySet, params string[] propertyPath)
{
    return entitySet.SelectDynamic(propertyPath) as IEnumerable<object>;
}
var list = db.YourEntity.SelectAsEnumerable("Name", "ID", "TestProperty.ID").ToList();

你需要做更多的工作才能得到你想要的——例如添加更好parsing和更多的功能等(这也适用于Select——不是OrderBy等)

于 2013-04-19T11:58:43.803 回答
0

解决了:

/// <summary>
/// Returns a queryable sequence of TResult elements which is composed through specified property evaluation.
/// </summary>
public static IQueryable<TResult> WithInfo<TItem, TProperty, TResult>(this IQueryable<TItem> q, Expression<Func<TItem, TProperty>> propertySelector, Expression<Func<TItem, TProperty, TResult>> resultSelector)
{
    ParameterExpression param = Expression.Parameter(typeof(TItem));
    InvocationExpression prop = Expression.Invoke(propertySelector, param);

    var lambda = Expression.Lambda<Func<TItem, TResult>>(Expression.Invoke(resultSelector, param, prop), param);
    return q.Select(lambda);
}
于 2013-06-06T14:40:54.730 回答