2016-01-04 22 views
5

aşağıdaki varlık vardır:Linq Grubu tarafından ve toplamı problemleri

abonelikler listesiyle bir hesap sınıfı:

public class Account 
{ 
    /// <summary> 
    /// Account ID 
    /// </summary> 
    public string ID { get; set; } 

    /// <summary> 
    /// A List with all subscriptions 
    /// </summary> 
    public IEnumerable<Subscription> Subscriptions { get; set; } 
} 

varyasyonları içeren bir liste abonelik sınıf ve eklentileri:

public class Subscription 
{ 
    /// <summary> 
    /// Subscription ID 
    /// </summary> 
    public string ID { get; set; } 

    /// <summary> 
    /// Quantity of the subscription. 
    /// </summary> 
    public int Quantity { get; set; } 

    /// <summary> 
    /// A list with all subscription add ons 
    /// </summary> 
    public IEnumerable<AddOn> AddOns { get; set; } 

    /// <summary> 
    /// A List with all subscription variations 
    /// </summary> 
    public IEnumerable<Variation> Variations { get; set; } 
} 

varyasyonları içeren bir liste sınıfı ekleyin:

public class AddOn 
{ 
    /// <summary> 
    /// Gets or Sets add on id 
    /// </summary> 
    public string ID { get; set; } 

    /// <summary> 
    /// Quantity of the add on. 
    /// </summary> 
    public int Quantity { get; set; } 

    /// <summary> 
    /// A List with all add on variations 
    /// </summary> 
    public IEnumerable<Variation> Variations { get; set; } 

} 

Ve varyasyon sınıfı: Ne yapmaya çalışıyorum grubuna ise

public class Variation 
{ 
    /// <summary> 
    /// Variation ID 
    /// </summary> 
    public string ID { get; set; } 

    /// <summary> 
    /// offerUri 
    /// </summary> 
    public string Code { get; set; } 

    /// <summary> 
    /// Variation Value 
    /// </summary> 
    public string Value { get; set; } 

    /// <summary> 
    /// Variation Name 
    /// </summary> 
    public string Name { get; set; } 

} 

tüm spesifik Kanunu ile eklentileri ve miktarını toplamak. Örneğin Denedim:

var groupAddOnsByCode = acc.Subscriptions.Select(s => s.AddOns.GroupBy(a => a.Variations.Select(v => v.Code).FirstOrDefault())).ToList(); 

Bu bir doğru grupları eklentiler ama kanununda başına toplam miktar ile abonelik grup başına eklentiler ile birlikte bir listesini istiyorum.

Örneğin, bir Abonelikte X eklenti numarası varsa ve her ekin Kodu 1, 2, ..., X ise, Kod eklerine ve bu Kodla toplam Miktar'a göre gruplamak istiyorum.

bugünkü yapısıyla bir sözde kodu (Kanunu atıfta Varyasyon için Class her sahiptir üzerine ekleyin):

Subscription { 
//a list with X number of add ons 
AddOn1 = { Variation = { Code = 1 }, Quantity = 2 }, 
AddOn2 = { Variation = { Code = 2 }, Quantity = 3 }, 
... 
AddOnX = { Variation = { Code = X }, Quantity = 4 } 
} 

sonucun aşağıdaki yapıya sahip olmadığını gibi bir şey olacak bekliyoruz beklediğim ne:

Subscription { 
    AddOn1 { Variation = { Code = 1 }, Quantity = totalAmountOfQuantityForAddOnsWithCode = 1 }, 
    ... 
    AddOnX { Variation = { Code = X }, Quantity = totalAmountOfQuantityForAddOnsWithCode = X }, 
} 

Sen kukla verileri sınamak için bu dotnetfiddle kullanabilirsiniz.

Uzun yazı için özür dilerim ve herhangi bir yardım için minnettar olacağım. Ayrıca C# ve Linq bilgimin sınırlı olduğunu aklımda tut. Doğru anladıysam, Ne istediğini bu tamamen emin değilim rağmen

+0

Tam o Variation.Code tarafından belirlenen master grubu, tek set haline her Abonelik gelen AddOns toplamak istiyorum açıklığa kavuşturmak ve nasıl? – ryanyuyu

+0

@ryanyuyu Evet, ve daha spesifik olmak için. 1, 2, 3 kodlu 20 eklentili bir aboneliğim olduğunu varsayalım. 3 Eklentiyle bir Abonelik ve aynı kodla her birinin toplam miktarını istiyorum. –

+0

Sadece emin olmak için, farklı abonelikler arasında farklı şeyleri birleştirmek istemiyor musunuz? Yani, her biri 10 eklentili 2 aboneliğiniz varsa, iki ayrı grup ekleme grubu ve 20'den bir grup değil misiniz? – ryanyuyu

cevap

5

, şu istenilen sonucu

var result = acc.Subscriptions.Select(s => new 
{ 
    Subscription = s, 
    AddOns = s.AddOns.SelectMany(a => a.Variations, (a, v) => new { a, v }) 
     .GroupBy(e => e.v.Code, (key, elements) => new 
     { 
      Code = key, 
      Quantity = elements.Sum(e => e.a.Quantity) 
     }).ToList() 
}).ToList(); 
+0

Çok teşekkürler. Testlerimi yapacağım ve bunu kabul edeceğim :) –

2

doğurabileceğini, bu addOns bir List<AddOn>

var codes = addOns.SelectMany(a => a.Variations).Select(v => v.Code).Distinct(); 

var addOnsByCode = new List<AddOn>(); //your desired result 
foreach (var code in codes) 
{ 
    var addOnsWithThisCode = addOns.Where(a => a.Variations.Any(v => v.Code == code)); 
    addOnsByCode.Add(new AddOn{ 
     Variations = new List<Variation> { new Variation { Code = code } }, 
     Quantity = addOnsWithThisCode.Sum(a => a.Quantity), 
     ID = string.Join("_", addOnsWithThisCode.Select(a => a.ID)) //not required> 
    }); 
} 

olduğu yerlerde denemek örneğin,

var addOns = new List<AddOn> { 
    new AddOn { 
     ID = "1", 
     Quantity = 5, 
     Variations = new List<Variation> 
     { 
      new Variation { Code = "A" }, 
      new Variation { Code = "B" } 
     } 
    }, 
    new AddOn { 
     ID = "2", 
     Quantity = 7, 
     Variations = new List<Variation> 
     { 
      new Variation { Code = "B" }, 
      new Variation { Code = "C" } 
     } 
    }, 
    new AddOn { 
     ID = "3", 
     Quantity = 9, 
     Variations = new List<Variation> 
     { 
      new Variation { Code = "D" }, 
      new Variation { Code = "A" } 
     } 
    }, 
}; 
+0

Cevabınız ve emeğiniz için çok teşekkürler, ama ben IvanStoev ile gideceğim. –

+1

Elbette, hangisi yaklaşıyorsa probleminizi çözebilirsiniz. –

2

Sorununuzu doğru bir şekilde kullanmam, aşağıdaki yöntemin yardımcı olacağını düşünüyorum. Subscription sınıfında eklentilerini Varyasyon Kodları ile gruplamak ve sonra çeşitli kodların miktarlarını toplamak için bir yöntem ekledim. Kodumun anahtarı, Kod ve Miktar'ı eşleştiren ayrı öğelere birden çok varyantla tek bir Eklentiyi kırmak için SelectMany kullanıyor. Daha sonra kırılan elemanları gruplayabilirsiniz.

public Dictionary<string, int> GetAddonGroups() 
{ 
    //spreading out each Add-on into multiple elements, each with a Code and quantity 
    var addOnVariationsWithQuantity = this.AddOns 
     .SelectMany(ad => ad.Variations 
        .Select(v => new {Code = v.Code, Quantity = ad.Quantity})); 

    //group by Code and Sum the quantity 
    var addOnGroups = addOnVariationsWithQuantity 
         .GroupBy(v => v.Code) 
         .ToDictionary(grp => grp.Key, 
             grp => grp.Sum(el => el.Quantity)); 
    return addOnGroups; 
} 

Forked Fiddle

+0

Cevabınız ve emeğiniz için çok teşekkürler ama ben IvanStoev ile gideceğim. –

+1

@AlexChar sorun değil. SelectMany ile benzer ish yaklaşımlarına sahip olduk. Bunun biraz yardımcı olmasına sevindim. – ryanyuyu