进行特定的Sum <t>

时间:2019-01-30 14:18:34

标签: c# linq

我有一个Contract内的类ObservableCollection<Repere>

class Contract : INotifyPropertyChanged
{
    private ObservableCollection<Repere> listReperes;
    public ObservableCollection<Repere> ListReperes
    {
        get { return listReperes; }
        set
        {
            listReperes = value;
            NotifyPropertyChanged(ref listReperes, value); //NotifyPropertyChanged("ListReperes");
        }
    }
    ...
}

我的班级“曲目”有一个ObservableCollection<Operation>

class Repere : INotifyPropertyChanged
{
    private ObservableCollection<Operation> listOperations;
    public ObservableCollection<Operation> ListOperations
    {
        get { return listOperations; }
        set
        {
            NotifyPropertyChanged(ref listOperations, value);

        }
        ...
    }
}

最后,我的课Operation如下:

public class Operation : INotifyPropertyChanged
{
    private int qtyFinished;
    public int QtyFinished
    {
        get { return qtyFinished; }
        set
        {
            qtyFinished = value;
            this.NotifyPropertyChanged("QtyFinished");
        }
    }
    public long ID { get; set; }
    ...
}

我的合同有一个Repere列表,每个Repere都有一个操作列表,我想要的是按名称对我的Repere进行分组,并获取每个Repere的操作总数。

现在,我执行以下操作:

List<Repere> liste_rep_group = liste_rep.GroupBy(l => l.Name)
    .Select(cl => new Repere
    {
        Quantite = cl.Sum(c => c.TotalQuantity),
        TotalQuantity = cl.Sum(c => c.TotalQuantity),
        ID = -1,
        IdAff = cl.First().IdAff,
        Name = cl.First().Name,
        NameOri = cl.First().Name,
        Nom_aff = cl.First().Nom_aff,
        Profil = cl.First().Profil,
        Longueur = cl.First().Longueur,
        Hauteur = cl.First().Hauteur,
        Largeur = cl.First().Largeur,
        Poids = cl.First().Poids,
        Priorite = cl.Min(c => c.Priorite),
        ListOperations = new ObservableCollection<Operation>(),
    }).ToList();

由于我不知道如何对ListOperations进行“求和”,因此我需要手动进行

foreach (Repere rep in liste_rep)
{
    Repere repFound = liste_rep_group.FirstOrDefault(x => x.Name == rep.Name);
    if (repFound != null)
    {
        foreach (Operation op in rep.ListOperations)
        {

            Operation opFound = repFound.ListOperations.FirstOrDefault(y => y.ID == op.ID);
            if (opFound != null)
            {
                opFound.QtyFinished += op.QtyFinished;
                opFound.QtyTot += op.QtyTot;
            }
            else
            {
                Operation newOp = new Operation();
                newOp.Nom = op.Nom;
                newOp.ID = op.ID;
                newOp.Clone(op);
                repFound.ListOperations.Add(newOp);
            }
        }
    }
}

我想要的是:

  • 按Repere名称将我的ObservableCollection分组。
  • 汇总每个具有相同名称的曲目的操作列表

总和可能是这样的:

public ObservableCollection<Operation> Sum(operation1, operation2)
{
   ObservableCollection<Operation> mySum=new ObservableCollection<Operation>();
   if(operation1.ID==operation2.ID)
   {
      operation1.QtyFinished+=operation2.QtyFinished;
      mySum.Add(operation1);
      return mySum;
   }
   else
   {
      mySum.Add(operation1);
      mySum.Add(operation2);
      return mySum;
   }
}

是否可以在Operation类中定义一个Sum函数,用于定义如何对ObservableCollection求和?

编辑:这是所要求的示例:

如果我想对2个Repere求和,结果求和操作将是这样的:

Repere1
   ID_operation      Quantity
   1                 2
   2                 1
   3                 5
Repere1
   ID_operation      Quantity
   1                 2
   2                 1
   4                 2

结果将是:

Repere1

   ID_operation      Quantity
   1                 4
   2                 2
   3                 5
   4                 2

编辑:

好的,一切正常,只需要为ObservableCollection进行更改即可:

ListOperations = new ObservableCollection<Operation>(cl.SelectMany(g=>g.ListOperations).GroupBy(o=>o.ID)
                .Select(go => new Operation
                    {
                        ID = go.First().ID,
                        QtyFinished = go.Sum(o => o.QtyFinished),
                        Color=go.First().Color,
                    }))

1 个答案:

答案 0 :(得分:1)

这是一种方法:

class Repere
{
    public string Name { get; set; }
    public List<Operation> Operations { get; set; }
}

class Operation
{
    public int Id { get; set; }
    public int Quantity { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var data = new List<Repere>
        {
            new Repere { Name = "Repere1", Operations = new List<Operation>
            {
                new Operation { Id = 1, Quantity = 2 },
                new Operation { Id = 2, Quantity = 1 },
                new Operation { Id = 3, Quantity = 5 }
            }},
            new Repere { Name = "Repere1", Operations = new List<Operation>
            {
                new Operation { Id = 1, Quantity = 2 },
                new Operation { Id = 2, Quantity = 1 },
                new Operation { Id = 4, Quantity = 2 }
            }},
        };

        var result = data.GroupBy(r => r.Name)
            .Select(gr => new
            {
                Name = gr.Key,
                Operations = gr.SelectMany(g => g.Operations)
                    .GroupBy(o => o.Id)
                    .Select(go => new { Id = go.Key, Quantity = go.Sum(o => o.Quantity)})
            });

        foreach (var r in result)
        {
            Console.WriteLine(r.Name);
            foreach (var o in r.Operations)
            {
                Console.WriteLine($"\t{o.Id}\t{o.Quantity}");
            }
        }

        Console.ReadKey();
    }
}

此外,您无需在ListOperations上有一个setter即可将对集合的更改正确地通知给UI-各个项(实现INotifyPropertyChanged)会提高其自己的通知(即,这些通知将不使用集合的set方法)。