#c# #linq
#c# #linq
Вопрос:
Я не уверен, как назвать мою проблему, хотя я упомянул в теме как «Несколько уровней агрегации».
Я хотел бы объединить различные измерения представленных данных. В этом примере я пытаюсь получить данные агрегирования с помощью SalesCode
и более подробной агрегации с помощью AccountId
. Таким образом, в принципе, я мог бы получить учетные записи, которые были связаны с уровнем агрегирования продаж.
Следовательно, результат, который я должен получить, должен быть таким:
Мое требование — сопоставить данные со следующим классом:
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;
}
}
Из следующих данных:
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
},
};
До сих пор я пробовал следующие способы в работе, о которой я упоминаю ниже, но я не знаю, как получить агрегацию 2-го уровня, которая выполняется по идентификатору учетной записи.
Ошибка DotNetFiddle:https://dotnetfiddle.net/SxGdDD
Класс Trade выглядит следующим образом:
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;
}
}
Ответ №1:
Вам нужен другой 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));
}
}
Комментарии:
1. Спасибо, @stephan-bauer Сработал, понравилось, прелесть! 🙂