2016-10-07 13 views
11

to LINQ kwerendy UżyłemJak generować zduplikowane elementy na liście przy użyciu LINQ?

var result = (from price in inventoryDb.Pricing.AsNoTracking()    
       where price.Quantity > 0m 
       select new 
       { 
       TagNo = price.TagNo, 
       SellingRate = price.SellingRate, 
       Quantity = price.Quantity   
       }).ToList(); 

Na podstawie wartości Quantity muszę generować zduplikowane pozycje na liście.

wyjściowa:

result = [0]{TagNo="100", SellingRate=1500.00, Quantity=1} 
     [1]{TagNo="101", SellingRate=1600.00, Quantity=2} 

Oczekiwany wynik:

result = [0]{TagNo="100", SellingRate=1500.00} 
     [1]{TagNo="101", SellingRate=1600.00} 
     [2]{TagNo="101", SellingRate=1600.00} 

Odpowiedz

8

Można użyć Enumerable.SelectMany + Enumerable.Range:

var result = inventoryDb.Pricing.AsNoTracking() 
    .Where(p => p.Quantity > 0m) 
    .SelectMany(p => Enumerable.Range(0, p.Quantity) 
     .Select(i => new 
       { 
       TagNo = p.TagNo, 
       SellingRate = p.SellingRate  
       })) 
    .ToList(); 

Jeśli tak nie jest t obsługiwane przez Twojego dostawcę LINQ (np. Linq-To-Entities), najłatwiej jest użyć Linq-To-Objects. Aby uniknąć sytuacji, wszystko jest ładowany do pamięci należy użyć AsEnumerable po Where:

var result = inventoryDb.Pricing.AsNoTracking() 
    .Where(p => p.Quantity > 0m) 
    .AsEnumerable() 
    .SelectMany(p => Enumerable.Range(0, p.Quantity) 
     .Select(i => new 
       { 
       TagNo = p.TagNo, 
       SellingRate = p.SellingRate  
       })) 
    .ToList(); 
4

Zgodnie ze składni zapytań wystarczy dodać Enumerable.Repeat następująco:

var result = (from price in inventoryDb.Pricing.AsNoTracking() 
       where price.Quantity > 0m 
       from dup in Enumerable.Repeat(0,price.Quantity) 
       select new 
       { 
       TagNo = price.TagNo, 
       SellingRate = price.SellingRate,   
       }).ToList(); 

Jeśli rzeczywiście LINQ do podmioty nie obsługuje następnie dodać AsEnumerable jak następuje:

var result = (from price in inventoryDb.Pricing.AsNoTracking() 
               .Where(p => p.Quantity > 0m) 
               .AsEnumerable() //Loads only the filtered items to memory    
       from dup in Enumerable.Repeat(0,price.Quantity) 
       select new 
       { 
       TagNo = price.TagNo, 
       SellingRate = price.SellingRate,   
       }).ToList(); 

można również użyć Enumerable.Range, ale dlatego, że nie korzystasz z wartości tej kolekcji (i moim zdaniem również dlatego, że lepiej opisuje to, co robisz) postanowiłem po prostu wybrać z Repeat

+1

To oczywiste rozwiązanie LINQ To Objects. Pytanie brzmi jednak, czy w ogóle działałoby to z EF (zauważ "inventoryDb.Pricing.AsNoTracking()"). Założę się na 'NotSupportedException' :) –

+1

@IvanStoev, Po prostu dodaj' .AsEnumerable() 'przed wywołaniem' Enumerable.Repeat'. – kiziu

+0

@IvanStoev - Dzięki za zauważenie :) masz rację i zapomniałem tego sprawdzić. Zobacz aktualizację –