2016-10-07 3 views
11

это LINQ запрос я использовалКак создать повторяющиеся элементы в списке с помощью 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(); 

Основываясь на значении Quantity мне нужно для создания повторяющихся элементов в списке.

Выход:

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

Ожидаемый результат:

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

ответ

8

Вы можете использовать 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(); 

Если это не t, поддерживаемый вашим провайдером LINQ (f.e. Linq-To-Entities), проще всего использовать Linq-To-Objects. Чтобы избежать этого, все загружается в память, вы должны использовать AsEnumerable после 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

Keeping с синтаксисом запросов просто добавьте Enumerable.Repeat следующим образом:

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(); 

Если на самом деле LINQ к объектам не поддерживает затем добавить AsEnumerable как следующим образом:

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(); 

Вы также можете использовать Enumerable.Range, но поскольку вы не используете ценность этой коллекции (и, на мой взгляд, просто то, что она лучше описывает, что вы делаете) Я решил просто пойти с Repeat

+1

Это очевидное решение LINQ To Objects. Вопрос в том, будет ли это вообще работать с EF (обратите внимание на «inventoryDb.Pricing.AsNoTracking()»). Я ставлю свою ставку на 'NotSupportedException' :) –

+1

@IvanStoev, просто добавьте' .AsEnumerable() 'перед вызовом' Enumerable.Repeat'. – kiziu

+0

@ ИванСтоев - Спасибо за замечание :) Вы правы, и я забыл проверить это. См. Обновление –

Смежные вопросы