AVV
AVV

Reputation: 181

In C# Linq, how to initialize IQueryable or var variable when the type is not known, and linq query returns dynamic fields/object

Original code (no change here)

// present code which need not be changed
public class StatementHelper
{
    public List<Xyz> GetStatement()
    {
        // other code
        var result1 = (from a in db.AIAFTERM
               from b in db.INVM.InnerJoin(b => b.ContId == a.Id)
               where ...
               group a.MANTS by new
               {
                  ....
               } into g
               select new // not a strongly typed object. and I cannot change this
               {
                   EmpId = g.Key.Column1,
                   GlpIndex = g.Key.Column2
                   GlpIndexValue = g.Key.Column3
               });
        
        result1 = sortFilterCalculate(result1, empId: x=> x.EmpId);

        var result2 = (from x in result1
                              from acc in db.ACCOUNT.LeftJoin(acc => acc.EmpId == x.EmpId);
                              
        // rest of the code
    }
}       

public class Calculator {
    public IQueryable<T> sortFilterCalculate(IQueryable<T> uncalculated, Expression<Func<T, string>> empId) {
        // filter, calculate and return the result
    }
}

I want to change the above code to the one like shown below, so that result1 is derived based on a condition. What is the right syntax to declare result1. Data in result1 is not of strongly-typed object and I cannot change that. The sortFilterCalculate method takes the input of this list, and also requires the 2nd param as the expression which fails at compile time.

public class StatementHelper
{
    public List<Xyz> GetStatement(bool isActive)
    {
        // other code
        // what is the syntax to declare the variable result1
        
        IQueryable<dynamic> result1 = null;
        
        if(some_condition == true) {
            result1 = (from a in db.AIAFTERM
                   from b in db.INVM.InnerJoin(b => b.ContId == a.Id && a.IsActive == true)
                   where ...
                   group a.MANTS by new
                   {
                      ....
                   } into g
                   select new
                   {
                       EmpId = g.Key.Column1,
                       GlpIndex = g.Key.Column2
                       GlpIndexValue = g.Key.Column3
                   });
        } else {
            result1 = (from a in db.AIAFTERM
                   from b in db.INVM.InnerJoin(b => b.ContId == a.Id)
                   where ...
                   group a.MANTS by new
                   {
                      ....
                   } into g
                   select new
                   {
                       EmpId = g.Key.Column1,
                       GlpIndex = g.Key.Column2
                       GlpIndexValue = g.Key.Column3
                   });
        
        }
        
        result1 = sortFilterCalculate(result1, empId: x=> x.EmpId);/// --> shows compile error at x.EmpId, An expression tree may not contain dynamic operation
        // shows compile error 

        var result2 = (from x in result1
                              from acc in db.ACCOUNT.LeftJoin(acc => acc.EmpId == x.EmpId);
                              // above statement shows compile error /// --> shows compile error at x.EmpId, An expression tree may not contain dynamic operation
                              
        // rest of the code
    }
}   
        

Upvotes: -2

Views: 185

Answers (1)

Marcelo Estriga
Marcelo Estriga

Reputation: 79

You can minimally modify the code you provided to use the ternary conditional operator with an implicitly typed variable, like below:

var result1 = 
    some_condition == true ?
    from a in db.AIAFTERM
    from b in db.INVM.InnerJoin(b => b.ContId == a.Id && a.IsActive == true)
    where ...
    group a.MANTS by new
    {
         ....
    } into g
    select new
    {
        EmpId = g.Key.Column1,
        GlpIndex = g.Key.Column2
        GlpIndexValue = g.Key.Column3
    } :
    from a in db.AIAFTERM
    from b in db.INVM.InnerJoin(b => b.ContId == a.Id)
    where ...
    group a.MANTS by new
    {
        ....
    } into g
    select new
    {
        EmpId = g.Key.Column1,
        GlpIndex = g.Key.Column2
        GlpIndexValue = g.Key.Column3
    };

Upvotes: -1

Related Questions