Reputation: 9666
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
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