Hannele
Hannele

Reputation: 9666

Use Linq Expression object inside and outside query

I'm trying to accept a Func as a parameter to a function, and then use it both inside and outside a Linq query.

Here, idSelector is a Func of some kind which will return a particular SubLedger id in the Transaction object (e.g. t => t.SubLedger1).

public class Transaction {
    public int SubLedger1 { get; set; }
    public int SubLedger2 { get; set; }
    public int SubLedger3 { get; set; }

    public decimal Balance { get; set; }
}

public IEnumerable<Transaction> GetSubLedger(DateTime StartDate, Func<Transaction, int> idSelector) {

    // simply returns IQueryable of all
    DbSet<Transaction> txns = txnRepo.GetAll(); 

    // get opening balance for each sub ledger
    var subLedgers = txns.Where(t => t.Date < StartDate)
        .GroupBy(idSelector, t => t, (id, txn) => new { ID = id, Balance = txn.Sum(t => t.Amount) })
        .ToDictionary(t => t.ID, t => t.Balance);

    // fill running balance
    var filtered = txns.Where(t => t.Date >= StartDate).ToList();
    foreach (var t in filtered)
    {
        t.Balance = subLedgers[idSelector.Invoke(t)].Balance += t.Amount;
    }

    return filtered;
}

I need to use idSelector in two places: first in the Linq query to group all transactions into subLedgers, and second to get the running balance for the particular subledger in the filtered results. I realize that Linq requires an Expression<...> instead, but I can't quite figure out how to Invoke that in the second context.

It's possible I'm going about this the wrong way, is there some other way I should try? This question may also be a little muddled, I did try to pare down the code sample as much as possible, so please ask me if anything is unclear.

Upvotes: 1

Views: 345

Answers (1)

McGarnagle
McGarnagle

Reputation: 102743

Use Compile to get the invokeable method from the expression:

t.Balance = subLedgers[idSelector.Compile()(t)].Balance += t.Amount;

(Assuming idSelector is an Expression<Func<Transaction, int>>.)

Upvotes: 2

Related Questions