2012-07-16 43 views
0

我有一個帶有按鈕和datagridview的winform。Linq查詢優化以獲得更快的結果

的情況是:

我有一個winform:

    using System; 
     using System.Collections.Generic; 
     using System.ComponentModel; 
     using System.Data; 
     using System.Drawing; 
     using System.Linq; 
     using System.Text; 
     using System.Windows.Forms; 

     namespace WindowsFormsApplication1 
     { 
      public partial class Form1 : Form 
      { 
       public Form1() 
       { 
        InitializeComponent(); 
        CreateItems(); 
       } 

       private List<Store> stores = new List<Store>(); 

       public void CreateItems() 
       { 

        Store newStore1 = new Store(); 
        newStore1.StoreName = "My Store 1"; 
        newStore1.City = "My City 1"; 
        newStore1.PlannedSales = 10; 
        newStore1.RealizedSales = 5; 
        newStore1.SalesDate = new DateTime(2012, 01, 12, 12, 30, 54, DateTimeKind.Unspecified); 

        Store newStore2 = new Store(); 
        newStore2.StoreName = "My Store 2"; 
        newStore2.City = "My City 2"; 
        newStore2.PlannedSales = 200000; 
        newStore2.RealizedSales = 250000; 
        newStore2.SalesDate = new DateTime(2012, 04, 12, 12, 30, 54, DateTimeKind.Unspecified); 

        Store newStore3 = new Store(); 
        newStore3.StoreName = "My Store 3"; 
        newStore3.City = "My City 3"; 
        newStore3.PlannedSales = 100000; 
        newStore3.RealizedSales = 10000; 
        newStore3.SalesDate = new DateTime(2012, 05, 12, 12, 30, 54, DateTimeKind.Unspecified); 

        Store newStore4 = new Store(); 
        newStore4.StoreName = "My Store 1"; 
        newStore4.City = "My City 1"; 
        newStore4.PlannedSales = 20; 
        newStore4.RealizedSales = 10; 
        newStore4.SalesDate = new DateTime(2012, 02, 12, 12, 30, 54, DateTimeKind.Unspecified); 


        Store newStore5 = new Store(); 
        newStore5.StoreName = "My Store 1"; 
        newStore5.City = "My City 1"; 
        newStore5.PlannedSales = 30; 
        newStore5.RealizedSales = 20; 
        newStore5.SalesDate = new DateTime(2012, 03, 12, 12, 30, 54, DateTimeKind.Unspecified); 



        stores.Add(newStore1); 
        stores.Add(newStore2); 
        stores.Add(newStore3); 
        stores.Add(newStore4); 
        stores.Add(newStore5); 
       } 

       private void btnQuery_Click(object sender, EventArgs e) 
       { 
        var query1 = stores.GroupBy(x => new 
        { 
         x.City, 
         x.StoreName, 
         x.SalesDate.Year, 
         x.SalesDate.Month 

        }).Select(group => new 
        { 
         Planned = group.Sum(x => x.PlannedSales), 
         Realised = group.Sum(x => x.RealizedSales), 
         Count = group.Count(), 
         City = group.Key.City, 
         StoreName = group.Key.StoreName, 
         Year = group.Key.Year, 
         Month = group.Key.Month 
        }).OrderBy(x => x.Year).ThenBy(x => x.Month).Where(x => x.StoreName.Equals("My Store 1")); 

        List<Store> total = new List<Store>(); 

        foreach (var value in query1) 
        { 
         Store newStore = new Store() 
         { 
          MonthYear = value.Month.ToString() + " - " + value.Year.ToString(), 
          RealizedSales = value.Realised, 
          PlannedSales = value.Planned 

         }; 
         total.Add(newStore); 
        }; 


        var query2 = total.Select((s, i) => new 
        { 
         MonthYear = s.MonthYear, 
         RealizedSales = s.RealizedSales + total.Take(i).Sum(sa => sa.RealizedSales), 
         PlannedSales = s.PlannedSales + total.Take(i).Sum(sa => sa.PlannedSales) 
        }); 

        List<Store> totalFinal = new List<Store>(); 


        foreach (var value in query2) 
        { 
         Store newStore = new Store() 
         { 
          MonthYear = value.MonthYear, 
          RealizedSales = value.RealizedSales, 
          PlannedSales = value.PlannedSales 
         }; 
         totalFinal.Add(newStore); 
        }; 


        dataGridView1.DataSource = totalFinal; 

       } 
      } 

      public class Store 
      { 
       public string StoreName { get; set; } 
       public string City { get; set; } 

       public int PlannedSales { get; set; } 
       public int RealizedSales { get; set; } 

       public DateTime SalesDate { get; set; } 

       public string MonthYear { get; set; } 

      } 
     } 

當窗體被實例化,方法CreateItems被調用。此方法將填充列表與一些演示存儲數據。

當從表單按鈕被按下,比列表存儲以這樣的方式,將來自我列表存儲返回所有PlannedSalesRealizedSalesMonthYear查詢使用LINQ凡STORENAME =我的店1

查詢結果的一個例子是在這裏:http://i49.tinypic.com/vz1c6.jpg

任何想法如何優化此查詢,使其更簡單,但得到相同的結果?

基本上我只需要返回所有計劃和已實現的每月銷售額,僅針對特定商店名稱!

謝謝!

+0

在哪裏以及它是如何缺乏,你認爲它需要優化? – Mayank 2012-07-16 09:48:29

+0

我在silverlight sharepoint webpart中使用它,查詢列表中的很多項目時很慢,而且您的數據量很大。例如其他一些查詢可以很好地工作,除了這個和另一個非常相似的查詢之外。 – 2012-07-16 09:56:49

回答

0

因爲這應該是一樣容易:

var totalPlanned = 0; 
var totalRealized = 0; 
var result = stores.Where(s => s.StoreName.Equals("My Store 1")) 
        .Select(s => { 
         totalPlanned += s.PlannedSales; 
         totalRealized += s.RealizedSales; 
         return new Store(){ 
          MonthYear = s.SalesDate.ToString("MM - yyyy"), 
          PlannedSales = totalPlanned, 
          RealizedSales = totalRealized 

         }; 
        }); 

活生生的例子顯示,顯示同樣的結果旁邊原來的這個新代碼:http://rextester.com/PAF27531

+0

這適用於演示數據,但如果數據未按日期排序或者存在多個具有相同城市,名稱和日期的商店,則不會得到相同的結果。 – 2012-07-16 15:16:08

-1
from s in stores 
where s.StoreName == "My Store 1" 
group s by new { s.StoreName, s.SalesDate.Year, s.SalesDate.Month } into g 
select new 
{ 
g.Key.StoreName, 
MonthYear = g.Key.Year.ToString() + " - " + g.Key.Month.ToString(), 
Planned = g.Sum(st => st.PlannedSales), 
Realized = g.Sum(st => st.RealizedSales) 
} 
+0

這給了OP的原始結果一個完全不同的結果。 http://rextester.com/XQOO40579 – Jamiec 2012-07-16 10:08:35