2016-10-07 13 views
11

đây là LINQ truy vấn Tôi đã sử dụngLàm cách nào để tạo các mục trùng lặp trong danh sách bằng 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(); 

Dựa trên giá trị Quantity tôi cần phải tạo bản sao bản ghi trong danh sách.

Output:

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

Dự kiến ​​kết quả:

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

Trả lời

8

Bạn có thể sử dụng 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(); 

Nếu đó là không t được nhà cung cấp LINQ của bạn hỗ trợ (f.e. Linq-To-Entities), cách dễ nhất là sử dụng Linq-To-Objects. Để tránh điều đó tất cả được nạp vào bộ nhớ bạn nên sử dụng AsEnumerable sau 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

Giữ với cú pháp truy vấn chỉ cần thêm một Enumerable.Repeat như sau:

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

Nếu thực sự LINQ to Entities không hỗ trợ sau đó thêm AsEnumerable như sau:

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

Bạn cũng có thể sử dụng Enumerable.Range nhưng vì bạn không sử dụng giá trị của bộ sưu tập đó (và theo ý kiến ​​của tôi cũng chỉ mô tả tốt hơn những gì bạn đang làm) Tôi quyết định chỉ cần đi với Repeat

+1

Đó là giải pháp LINQ To Objects rõ ràng. Câu hỏi là mặc dù điều này sẽ làm việc ở tất cả với EF (thông báo 'inventoryDb.Pricing.AsNoTracking()'). Tôi sẽ đặt cược vào 'NotSupportedException' :) –

+1

@IvanStoev, Chỉ cần thêm '.AsEnumerable()' trước khi gọi 'Enumerable.Repeat'. – kiziu

+0

@IvanStoev - Cảm ơn bạn đã thông báo :) bạn đúng và tôi quên kiểm tra điều đó. Xem cập nhật –

Các vấn đề liên quan