我希望将运行时构建的表达式(CustomExpression)与普通的select clausule结合起来。如果没有手动构建整个表达式,C#中有没有办法做到这一点?
var dto = iqueryable.Select(d => new DTO()
{
X = d.X,
Y = d.Y,
Z = CustomExpression
}
其中CustomExpression
是这样的:
private Expression<Func<EntityTypeFromIQueryable, string>> CustomExpression() {
get {
// there is manually built expression like this:
return x => x.Blah
}
}
答案 0 :(得分:2)
您必须先在表达式中插入某种可编辑的占位符(如扩展方法)。然后,在运行时,您可以使用表达式访问者修改表达式,以使用实际的lambda表达式替换“占位符”。由于您的实际表达式使用不同的参数(d
与x
),因此您必须将其替换为“原始”表达式。
事实上,我在this project内玩这种场景,我试图抽象这种表达方式。你的“组合”看起来就像那样:
var dto = iqueryable.ToInjectable().Select(d => new DTO()
{
X = d.X,
Y = d.Y,
Z = d.CustomExpression()
}
public static class CustomExpressions
{
[InjectLambda]
public static string CustomExpression(this EntityTypeFromIQueryable value)
{
// this function is just a placeholder
// you can implement it for non LINQ use too...
throw new NotImplementedException();
}
public static Expression<Func<EntityTypeFromIQueryable, string>> CustomExpression()
{
return x => x.Blah
}
}
调用ToInjectable()
围绕原始 Queryable 创建一个轻量级代理,以便在执行前修改表达式,如上所述。属性InjectLambda
将“占位符”标记为“在这里注入lambda”。按照惯例,ToInjectable()
返回的实际表达式将插入到所需位置。
答案 1 :(得分:-1)
您可以通过以下方式执行此操作:
static void MultipleExpressionInSelectStatement()
{
List<person> p = new List<person>();
p.Add(new person() { name = "AB", age = 18 });
p.Add(new person() { name = "CD", age = 45 });
var dto = p.Select(d => new person()
{
name=d.name,
age=p.Select(ListExtensions.CustomExpression()).ElementAt(0)
});
}
//customExpression
public static class ListExtensions
{
public static Func<person, int> CustomExpression()
{
return x => x.age;
}
}
//Person Object
public class person
{
public string name { get; set; }
public int age { get; set; }
}