我的扩展方法的完整定义是第一位的。
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
类中获取一些Ticket
- linq-supported-info,并预测Ticket
和string
信息到序列:
var tickets2 = tickets.Select(W => new { Ticket = W, Info = W.Name + "123"});
最后,我希望我的方法返回IQueryable
,它会在resultSelector
中选择用户想要的内容。此结果选择器选择票证和info参数,并生成用户希望它生成的内容。我有点坚持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
来获取两个属性Ticket
和Info
,但是需要一个类型,我在tickets2
中有匿名类型
接下来,(我猜)我需要在lambda
内使用tickets2
来生成方法结果IQueryable<TResult>
。
那么我应该如何构建最终表达式呢?
答案 0 :(得分: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
等。
答案 1 :(得分: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);
}