顯示包含「LINQ」標籤的文章。顯示所有文章
顯示包含「LINQ」標籤的文章。顯示所有文章

2013年2月28日星期四

SQL to LINQ的GroupBy解說

SQL中的GROUP BY用法,大家都知道。
但若果轉移到LINQ上,或許會感到迷惑,因為寫SQL都久了,把SQL語法的直覺性放在LINQ可是不行。

聽起來很抽象吧? 來看看示範
AdventureWorks 2008 LT Sample DB 配合 LINQPad做示範。

我想找出SalesOrderID : 71920的貨物總和/價值總和,SQL就很容易會寫出這樣,亦得出正確的結果。
SELECT SalesOrderID, SUM(OrderQty) as TotalQty, SUM(UnitPrice) as TotalPrice 
FROM SalesLT.SalesOrderDetail detail
WHERE detail.SalesOrderID = '71920'
GROUP BY  detail.SalesOrderID;



來到LINQ,如果把SQL的編寫概念放在LINQ,或許你會跟我一樣寫出 :
from detail in SalesOrderDetails
where detail.SalesOrderID.Equals(71920) 
group detail by detail.SalesOrderID into g
select g

但當然,結果是怪怪的。
得出來的是 IOrderedQueryable<IGrouping<Int32,SalesOrderDetail>>
因為在這裡的Group...By...其實只是意味著把SalesOrderID和SalesOrderDetail集合至IGrouping的"g"。
結果其實與下方Comment的差不多。



正確的寫法應該是用new keyword去建立新的class。
from detail in SalesOrderDetails
 where detail.SalesOrderID.Equals(71920) 
 group detail by detail.SalesOrderID into g
 select new { 
    /*Distinct() return Enumerable<Int32> , Sum() & First() to return Int32 */
  SalesOrderID = g.Select(item =>item.SalesOrderID).Distinct().First(), 
 TotalQty =  g.Select(item =>Convert.ToDouble(item.OrderQty)).Sum(),
 TotalPrice = g.Select(item =>item.UnitPrice).Sum()
}

上述的new keyword跟平時的功用相似 ( FileInfo fInfo = new FileInfo(); ),但在這裡是建立新的Class或Structs,而且是Anonymous Type,帶有SalesOrderID / TotalQty / TotalPrice 的Properties。

得出來的結果就會是 :


如果覺得語法太冗長,可以改寫成Method-Based的Syntax :
SalesOrderDetails.Where(sod => sod.SalesOrderID == 71920)
                 .GroupBy(sod => sod.SalesOrderID)
                 .Select(g => new {
                               SalesOrderId = g.Key,
                               TotalQty = g.Sum(i => Convert.ToDouble(i.OrderQty)),
                               TotalPrice = g.Sum(i => i.UnitPrice)
                   })


參考:
Method-Based Query Syntax
http://msdn.microsoft.com/en-us/library/bb669086.aspx
Query Syntax and Method Syntax in LINQ (C#)
http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx

2007年11月24日星期六

What are Lambda Expressions?

English:
Lambda expressions, new in Visual Basic 2008, are a handy addition to any programmer's toolbox. They are callable entities that are defined within a function, and they're first-class citizens; you can return a lambda expression from a function and you can pass lambda expressions to other functions. Lambda expressions were added to Visual Basic 2008, formerly code-named "Orcas," in order to support Language Integrated Queries (LINQ), which adds data programmability to Visual Basic (more on that later). As you use lambda expressions, you will begin to see the power and flexibility they promote. I invite you to sample the basic concepts of lambda expressions, explore their benefits, and witness how to use them to write more expressive programs.

http://msdn.microsoft.com/msdnmag/issues/07/09/BasicInstincts/default.aspx?loc=en

繁體中文:
Lambda 運算式是 Visual Basic 2008 的新增功能,也是所有程式設計師的工具箱不可或缺的利器。它們是定義在函式內的可呼叫實體,且是第一等公民;您可以從函式傳回 Lambda 運算式,也可以將 Lambda 運算式傳遞給其他的函式。Lambda 運算式是 Visual Basic 2008 (原來的名稱代碼為 "Orcas") 新增的部分,為的是要支援 Language Integrated Queries (LINQ),這可以提升 Visual Basic 的資料可程式性 (將於稍後詳述)。隨著您使用 Lambda 運算式,您將會了解到它們的威力與彈性。我竭誠邀請您來體驗 Lambda 運算式的基本概念、探索其優勢,以及目睹如何運用它們來撰寫更具表達力的程式。

http://msdn.microsoft.com/msdnmag/issues/07/09/BasicInstincts/default.aspx?loc=zx