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

Ответ 1

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

Если это не поддерживается вашим провайдером 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();

Ответ 2

Сохраняя синтаксис запроса, просто добавьте 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