Dynamically select LINQ SELECT fields at runtime

后端 未结 1 1583
-上瘾入骨i
-上瘾入骨i 2021-01-24 06:55

I have a LINQ query to a database, with multiple linked tables, and need to return (SELECT) different fields depending on inputs.

ClassA has ParamA, ParamB, and          


        
相关标签:
1条回答
  • 2021-01-24 07:09

    This may be a bit verbose, but Expressions can get that way, for example:

    var typeClassA = typeof(ClassA);
    var typeClassB = typeof(ClassB);
    
    var parameterExpressionP = Expression.Parameter(typeClassB, "p");
    var newExpression = Expression.New(typeClassB);
    
    var paramDPropertyExpression = Expression.Property(parameterExpressionP, "ParamD");
    var paramDMemberBinding = Expression.Bind(typeClassB.GetProperty("ParamD"), paramDPropertyExpression);
    
    var paramEPropertyExpression = Expression.Property(parameterExpressionP, "ParamE");
    var paramEMemberBinding = Expression.Bind(typeClassB.GetProperty("ParamE"), paramEPropertyExpression);
    
    var memberInitExpression = Expression.MemberInit(
        newExpression,
        paramDMemberBinding, paramEMemberBinding);
    
    var projectionExpression = Expression.Lambda<Func<ClassB, ClassB>>(memberInitExpression, parameterExpressionP);
    
    var parameterExpressionC = Expression.Parameter(typeClassA, "c");
    var selectParamExpression = Expression.Property(parameterExpressionC, "ClassBs");
    
    var selectExpression = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.Select),
        new[] { typeClassB, typeClassB },
        selectParamExpression, projectionExpression);
    
    var toListExpression = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.ToList),
        new[] { typeClassB },
        selectExpression);
    

    This will create an expression something like:

    c.ClassBs.Select(p => new ClassB() {ParamD = p.ParamD, ParamE = p.ParamE}).ToList()
    
    0 讨论(0)
提交回复
热议问题