LINQ选择中的多个表达式

本文关键字:表达式 选择 LINQ | 更新日期: 2023-09-27 18:08:50

我想结合我的表达式内置在运行时(CustomExpression)与普通的选择子句。有没有任何方法在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
    }
}

LINQ选择中的多个表达式

您必须首先在表达式中插入某种可编译的占位符(如扩展方法)。然后,在运行时,您可以使用 expression Visitor来修改表达式,将"占位符"替换为实际的lambda表达式。由于您的实际表达式使用不同的参数 (d vs. x),您必须将它们替换为"原始"表达式。

事实上,我在这个项目中正在玩这样的场景,我试图抽象这种表达管道。你的"combine"看起来就像这样:

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()返回的实际表达式被插入到所需的位置。

你可以这样做:

 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; }
}