简体   繁体   中英

Multiple Aggregation Levels in Linq

I am not sure what my issue to be called, although I mentioned in the subject as "Multiple Aggregation Levels".

I would like to Aggregate different dimensions of the data presented. In this Example, I am trying to get Aggregation data by SalesCode and in Detail Aggregation by AccountId . So basically, I could get the Accounts that were associated to the Sales Aggregation Level.

Hence the output I am ought to get should be like this:

在此处输入图片说明

My Requirement is to Map the data to the following Class:

public class Earning
{
    public string EntityId
    {
        get;
        set;
    }

    public string EntityName
    {
        get;
        set;
    }

    public string EntityType
    {
        get;
        set;
    }

    public int TradeCount
    {
        get;
        set;
    }

    public int OrderCount
    {
        get;
        set;
    }

    public decimal PrincipalAmount
    {
        get;
        set;
    }

    public decimal GrossBrokerage
    {
        get;
        set;
    }

    public decimal NetBrokerage
    {
        get;
        set;
    }

    public List<Earning> Detail
    {
        get;
        set;
    }
}

From the following data:

List<Trade> Trades = new List<Trade>(){ 
            new Trade{
                AccountId = "ACT01", 
                SalesCode = "STEVES", 
                PrincipalAmount = 100, 
                GrossBrokerage = 0.64M,
                NetBrokerage = 0.64M
            }, 
            new Trade{
                AccountId = "ACT02", 
                SalesCode = "STEVES", 
                PrincipalAmount = 100, 
                GrossBrokerage = 0.64M,
                NetBrokerage = 0.64M
            }, 
            new Trade{
                AccountId = "ACT01", 
                SalesCode = "STEVES", 
                PrincipalAmount = 50, 
                GrossBrokerage = 0.32M,
                NetBrokerage = 0.32M
            }, 
            new Trade{
                AccountId = "ACT03", 
                SalesCode = "GRAHAMS", 
                PrincipalAmount = 100, 
                GrossBrokerage = 0.64M,
                NetBrokerage = 0.64M
            }, 
        };

Until now I have tried the following ways in the working I am mentioning below, but I am clueless to get the 2nd Level aggregation, which is by AccountId.

DotNetFiddle: https://dotnetfiddle.net/SxGdDD

The Trade Class look like this:

public class Trade
{
    public string AccountId
    {
        get;
        set;
    }

    public string SalesCode
    {
        get;
        set;
    }

    public decimal PrincipalAmount
    {
        get;
        set;
    }

    public decimal GrossBrokerage
    {
        get;
        set;
    }

    public decimal NetBrokerage
    {
        get;
        set;
    }
}

You need another GroupBy .

    var results = (
        from r in Trades
        group r by r.SalesCode
        into g
        select new Earning()
        {
            EntityId = g.Key.ToString(),
            EntityName = g.Key.ToString(),
            TradeCount = g.Count(),
            OrderCount = g.Count(),
            PrincipalAmount = g.Sum(c => c.PrincipalAmount),
            GrossBrokerage = g.Sum(c => c.GrossBrokerage),
            NetBrokerage = g.Sum(c => c.NetBrokerage),
            Detail = g.GroupBy(c=>c.AccountId).Select(c => new Earning()
       // Added GroupBy ---^^
            {
                EntityId = c.Key,
                EntityName = c.Key,
                TradeCount = c.Count(),
                OrderCount = c.Count(),
                PrincipalAmount = c.Sum(p=>p.PrincipalAmount),
                GrossBrokerage =  c.Sum(p=>p.GrossBrokerage),
                NetBrokerage = c.Sum(p=>p.NetBrokerage),

            }).ToList(),
        }).ToList();

    foreach (var item in results)
    {
        Console.WriteLine(item.EntityId);
        Console.WriteLine(string.Format("Total Principal Amount: {0}", item.PrincipalAmount.ToString()));
        Console.WriteLine(string.Format("Total Gross Brokerage Amount: {0}", item.GrossBrokerage.ToString()));
        Console.WriteLine(string.Format("Total Net Brokerage Amount: {0}", item.NetBrokerage.ToString()));

        foreach (Earning detail in item.Detail)
        {
            Console.WriteLine(string.Format("-- Detail {0}/{1}", detail.EntityId, detail.EntityName));
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM