加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何在可以反转密钥的LINQ GroupBy中进行操作?

发布时间:2020-12-15 21:49:12 所属栏目:百科 来源:网络整理
导读:我想在LINQ中做一个复杂的GroupBy,但是我的键选择器出了问题.在下面的代码中,我能够通过我的密钥在一个方向上进行分组(通过SellerID,BuyerID),但我实际上还需要在反向中按我的密钥进行分组(通过SellerID,BuyerID或BuyerID,SellerID).我对此查询的最终目标是,
我想在LINQ中做一个复杂的GroupBy,但是我的键选择器出了问题.在下面的代码中,我能够通过我的密钥在一个方向上进行分组(通过SellerID,BuyerID),但我实际上还需要在反向中按我的密钥进行分组(通过SellerID,BuyerID或BuyerID,SellerID).我对此查询的最终目标是,当键被反转时,我需要使资产金额为负数.这将允许我净化双方存在的任何金额,然后我将最终只有那个特定方面的金额的记录.

以下代码应该解释它:

public class Record
{
    public int RecordID;
    public int SellerID;
    public int BuyerID;
    public List<Asset> Assets;
}

public class Asset
{
    public int AssetID;
    public decimal Amount;
}

var groups = new List<Record>
{
    new Record { RecordID = 1,SellerID = 100,BuyerID = 200,Assets = new List<Asset> { new Asset { AssetID = 5,Amount = 10 }}},new Record { RecordID = 2,Amount = 20 }}},new Record { RecordID = 3,Assets = new List<Asset> { new Asset { AssetID = 6,Amount = 60 }}},new Record { RecordID = 4,SellerID = 200,BuyerID = 100,Amount = 40 }}},new Record { RecordID = 5,Amount = 50 }}},new Record { RecordID = 6,Amount = 35 }}}
};

var result = groups.GroupBy(
    r => new { r.SellerID,r.BuyerID },r => r.Assets,(r,assets) => new
    {
        r.SellerID,r.BuyerID,AssetSummation = assets.SelectMany(asset => asset).GroupBy(a => a.AssetID).Select(a2 => new { AssetID = a2.Key,Amount = a2.Sum(a3 => a3.Amount) })
    });

我希望我的输出是以下内容:

>记录1

>卖方:100
>买方:200
>资产:

>资产

> AssetID:6
>金额:25

>记录2

>卖方:200
>买方:100
>资产:

> AssetID:5
>金额:60

我想我有一个好的开始,但我不知道从哪里开始.如何翻转键然后使金额为负数,这样我可以总结一下?我认为在我能够做到这一点后,我可以过滤出值为0的任何资产行(意味着记录是通过反向完成的).

编辑#1:也许我想要做的就是将groups变量加入到自身中以汇总连接两侧的所有匹配记录.因此,我最终会将左侧的SellerID加入右侧的BuyerID,将左侧的BuyerID加入右侧的SellerID.

解决方法

这是查询,它返回您的预期结果:

var result = records
    .SelectMany(r => new[] { r,new Record { // 1
           SellerID = r.BuyerID,BuyerID = r.SellerID,Assets = r.Assets.Select(a => new Asset { 
                        AssetID = a.AssetID,Amount = -a.Amount
                    }).ToList() }})
    .GroupBy(r => new { r.SellerID,r.BuyerID }) // 2
    .Select(g => new { // 3
           Seller = g.Key.SellerID,Buyer = g.Key.BuyerID,Assets = g.SelectMany(r => r.Assets)
                     .GroupBy(a => a.AssetID)
                     .Select(ag => new { 
                         AssetID = ag.Key,Amount = ag.Sum(a => a.Amount) })
                     .Where(x => x.Amount > 0) });

这个怎么运作?非常简单:

>对于每条记录,我选择两条记录 – 一条是原样,另一条是反向卖方和买方(所有资产都有负数).然后我用SelectMany压平所有记录.
>并按卖家和买家分组.
>休息是从每个组中简单计算资产数量.

BTW而不是返回匿名对象,您可以在最后一个select语句中创建Record和Asset对象.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读