Linq聚合对象和列表

时间:2011-06-29 11:26:38

标签: c# linq nhibernate

我使用NHibernate执行此查询:

    var test = _session.CreateCriteria(typeof(Estimation))
                .SetFetchMode("EstimationItems", FetchMode.Eager)
                .List();

“估算”可以有几个“EstimationItems”(数量,价格和ProductId)

我想要一个带有这些限制的“估计”列表:

  1. 图片上的“估算”代码一行(例如:2011/0001和2011/0003)
  2. 通过估计(每行上的平均值)“EstimationItems”的数量
  3. 通过估算(每行上的含义)每个“EstimationItems”的总价格(数量*价格)
  4. 我希望结构会更清晰,如下图所示。

    谢谢,

    enter image description here

    enter image description here

2 个答案:

答案 0 :(得分:2)

这是一个命题:

var stats =
    from estimation in test
    group estimation by estimation.code into gestimation
    let allItems = gestimation.SelectMany(x => x.EstimationItems)
    select new 
        {
            Code = gestimation.Key,
            ItemNumber = allItems.Count(),
            TotalPrice = allItems.Sum(item => item.Price * item.Quantity)
        };

现在,这将创建一个匿名类型,其中包含您想要的三个属性(估算代码,此估算代码的项目数以及此估算代码的项目总价)。

您可以根据具体需求进行调整。请记住,allItems是IEnumerable<EtimationItem>,包含属于具有相同代码的Estimation的所有EstimationItem。

如果你想在创建它的方法范围之外使用这个对象,你可以使用匿名类型,那么你应该创建一个类来保存这些值。

更正命题: 命题:

var stats =
    (from est in test.Cast<Estimation>()
    group est by est.code into gEst
    let allItems = gEst.SelectMany(est => est.EstimationItems).Cast<EstimationItem>()
    select new TestingUI
        {
            Code = gEst.Key,
            Quantity = gEst.Count(),
            Total = gEst.Sum(item => item.Price * item.Quantity)
        }).ToList();

答案 1 :(得分:0)

Dictionary<string, Tuple<int,decimal>> dico = new Dictionary<string, Tuple<int,decimal>>();
foreach (var itemEstimation in test)
{
    Estimation estimation = (Estimation)itemEstimation;
    if (dico.ContainsKey(estimation.Code) == false)
    {
        decimal total = 0;
        foreach (var item in estimation.EstimationItems)
        {
            EstimationItem estimationItem = (EstimationItem)item;
            total += item.Price * item.Quantity;
        }
        dico.Add(estimation.Code, new Tuple<int, decimal>(estimation.EstimationItems.Sum(x => x.Quantity), total));
    }
}

List<TestingUI> finalResult = new List<TestingUI>();
foreach (var item in dico)
{
    Tuple<int, decimal> result;
    dico.TryGetValue(item.Key, out result);
    finalResult.Add(new TestingUI() { Code = item.Key, Quantity = result.Item1, Total = result.Item2 }); 
}