使用Linq Expression对象进行内外查询

时间:2013-11-18 21:27:25

标签: c# linq

我正在尝试接受Func作为函数的参数,然后在Linq查询的内部和外部使用它。

此处,idSelector是某种Func,会在Transaction对象中返回特定的SubLedger ID(例如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;
}

我需要在两个地方使用idSelector:首先在Linq查询中将所有交易分组到subLedgers,然后在得到的过滤结果中获取特定分类帐的运行余额。我意识到Linq需要一个Expression<...>,但我无法弄清楚如何在第二个上下文中调用它。

我可能会以错误的方式解决这个问题,还有其他方法我应该尝试吗?这个问题也可能有些混乱,我确实试图尽可能地减少代码示例,所以请问我是否有任何不清楚的地方。

1 个答案:

答案 0 :(得分:2)

使用Compile从表达式中获取可调用的方法:

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

(假设idSelector是Expression<Func<Transaction, int>>。)