在 linq 查询中为商品添加订单号
我有以下 Linq 查询。 transactionData 是一个 IEnumerable。
var totalTransactions = 0;
viewModel.GroupedTransactions = transactionData
.GroupBy(x => new { DocumentId = x.DocumentId ?? "Un Documented" })
.Select(x => new GroupedTransaction
{
DocumentId = x.Key.DocumentId,
Transactions = x.Select(y => new Transaction
{
Amount = y.CommitAmount,
ActivityType = y.ActivityType,
Number = totalTransactions++
})
})
.OrderBy(x => x.DocumentId);
我试图将交易记录上的数字设置为递增数字。 这是行不通的,会在数字上留下空白。
查询后我还尝试了以下操作。
foreach (var item in viewModel.GroupedTransactions.SelectMany(x => x.Transactions))
{
item.Number = totalTransactions;
totalTransactions++;
}
这甚至没有更新 Number 值。 我做错了什么,或者是否有更简单的方法,使用简洁的 linq 扩展方法?
I have the following Linq query. transactionData is an IEnumerable.
var totalTransactions = 0;
viewModel.GroupedTransactions = transactionData
.GroupBy(x => new { DocumentId = x.DocumentId ?? "Un Documented" })
.Select(x => new GroupedTransaction
{
DocumentId = x.Key.DocumentId,
Transactions = x.Select(y => new Transaction
{
Amount = y.CommitAmount,
ActivityType = y.ActivityType,
Number = totalTransactions++
})
})
.OrderBy(x => x.DocumentId);
where I'm trying to set the Number on the Transaction record to be an incremented number.
This doesn't work, leaving gaps in the numbers.
I also tried the following after the query.
foreach (var item in viewModel.GroupedTransactions.SelectMany(x => x.Transactions))
{
item.Number = totalTransactions;
totalTransactions++;
}
This didn't even update the Number value.
What am I doing wrong, or is there a simpler way, with a neat linq extension method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是您正在关闭变量totalTransactions,您必须创建一个本地副本才能使用。 检查关闭循环变量被认为是有害的以获得更详细的解释。
像这样的事情应该有效:
对于使用 foreach 循环的第二种方法 - 您实际上是使用
SelectMany()
创建一个新的枚举,随后将其丢弃:相反,您必须强制对集合进行急切评估通过使用
ToList()
创建一个可以安全修改的集合。The problem is that you are closing over the variable
totalTransactions
, you have to create a local copy to use. Check Closing over the loop variable considered harmful for a more detailed explanation.Something like this should work:
For your second approach with the foreach loop - you are actually creating a new enumeration with
SelectMany()
that you subsequently just throw away:Instead you have to force eager evaluation of your collection by using
ToList()
to create a collection you can safely modify.另一种思考方式是,您有两个序列:
并且您想要获得一个序列,即带有 id 的事务。当我们想要组合两个序列时,我们可以使用
Zip
运算符:这是您想要的吗?
Zip 组合两个序列,直到到达其中一个序列的末尾。这就是为什么可以使用 Enumberable.Range 来获取比我们实际需要的更大范围的数字。
Another way to think about it is that you have two sequences:
And you want to get one sequence, transactions with ids. When we want to combine two sequences, we can use the
Zip
operator:Is this what you had in mind?
Zip combines two sequences until it reaches the end of one of the sequences. Thats why it is ok tu Enumberable.Range to get a much larger range of numbers than we actually need.