所以我有一个名为Transactions的列表。
var itemA = new TransactionItem() { ProductId = 1, Quantity = 2 };
var itemB = new TransactionItem() { ProductId = 1, Quantity = 3 };
var tranA = new Transaction() { Type = TransactionType.credit, Items = new List<TransactionItem>() { itemA } };
var tranB = new Transaction() { Type = TransactionType.credit, Items = new List<TransactionItem>() { itemB } };
var tranC = new Transaction() { Type = TransactionType.debit, Items = new List<TransactionItem>() { itemA } };
var transactions = new List<Transaction>() { tranA, tranB };
如何获得取消Credits和Debits的分组;即在上面我有两个学分,其中ProductID等于1,总计5,和一个借记,其中ProductID等于1,总计2,所以我想投影一个新的transactionItems列表,显示产生的正数。
(背景:我正在尝试创建一个功能,该功能可以获取一系列交易并确定所有信用额并记入一个人应该保留的项目。)
答案 0 :(得分:1)
这应该可以解决您的问题
transactions.SelectMany(t => t.Items, (t, ti) => new { t.Type, ti.ProductId, ti.Quantity })
.GroupBy(x => x.ProductId, x => x.Type == TransactionType.credit ? x.Quantity : -x.Quantity)
.Select(x => new TransactionItem
{
ProductId = x.Key,
Quantity = x.Sum()
})
结果是
包含一个TransactionItem的集合,其值为:{ProductId = 1,Quantity = 3}
一些改进
如果您可以将TransactionType更改为此
public enum TransactionType
{
credit = 1,
debit = -1
}
然后LINQ查询可以简化为
transactions.SelectMany(t => t.Items, (t, ti) => new { t.Type, ti.ProductId, ti.Quantity })
.GroupBy(x => x.ProductId, x => (int)x.Type * x.Quantity)
.Select(x => new TransactionItem
{
ProductId = x.Key,
Quantity = x.Sum()
})
答案 1 :(得分:0)
我不是100%肯定你的意思是“取消信用和借记”,但听起来好像你想从另一个中减去一个?
// first, use SelectMany() to flatten the "list of lists" structure
var result = transaction.SelectMany(
// for each transaction, select all items
t => t.Items,
// for each (transaction, item) pair, select out
// an anonymous type with product id and quantity (I'm using Type
// here to give Quantity a sign, although I'm not sure that's
// what you meant)
(t, ti) => new
{
ti.ProductId,
t.Type == TransactionType.credit ? ti.Quantity : -ti.Quantity
}
)
// take the big list and group up by product id
.GroupBy(t => t.ProductId)
// for each group, aggregate a new item with the sum quantity
.Select(g => new TransactionItem { ProductId = g.Key, Quantity = g.Sum() })
// remove items where everything canceled out
.Where(t => t.Quantity != 0)
.ToList();