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

2013年2月27日星期三

Xamarin (MonoTouch) 免費 Starter Editon

前幾天收到一封Email是Xamarin公司的MVP Offer,可以免費取得價值USD$1,800的Xamarin Business edition,可以用C#語法建立誇平台的iOS和Android程式。

不過有權利就有義務,暫時實在對手機程式的興趣不及其他範疇。
而且沒時間再做更多"義務工作",例如上官方討論區解答問題等等,所以暫時與這東西無緣。

其實我認為Android/iOS開發方面的資料十分充足,如果是C#的開發人員,轉寫Java或理解Android SDK根本沒難度。
是新手的話,為何不學Java,而刻意去學C#使用Mono呢?

所以Xamarin 的前身 MonoTouch推出至今三年有多,其實眼見國外都都反應都有點冷清。
即使官方的討論區也是如此。

如不是MVP的話,新版本2.0有Starter的Free Editon。
之此之前,任何版本都是收費的,推出免費版本加速普及都是必須的。

Xamarin Starter Editon
http://blog.xamarin.com/announcing-xamarin-2.0/

2013年2月26日星期二

Bootstrap Form Builder For ASP.NET MVC Scaffolding

先藉機說一說我與Scaffolding的話。

Scaffolding這玩意,早在我之前的工作上,需要寫Ruby on Rails已經玩過,當時在Aptana RadRails上工作,其實都幾莫名其妙的,很多地方都不明白。
到上年用ASP.NET 4當中的Dynamic Data技術,再到現在ASP.NET MVC4,一個Web程式中,總會有機會依賴到Scaffolding。

Scaffolding是什麼?
不論ASP.NET/PHP還是ROR,在MVC架構來說,Scaffolding其實是透過一個Data Model,去產生所需的Controller和View,
當中Controller含有一般CURD動作如Insert/Update/Delete/List/Detail等等,而View亦會自動化產生相應的HTML Form。
其中一個好處當然是可以很快捷就做到一個含有Edit/Delete/View的Grid列表程式。
但我必須說明,Scaffold出來的Form是給你再修改,完美它才使用,並不宜立即Production用。
可參考Why do RoR professionals NOT use Scaffolding?
唯ASP.NET Dynamic Data例外,因為Dynamic Data做的甚至比MVC4還要多。

之所以介紹這個Bootstrap Form Builder,除了Bootstrap是現在最火紅的CSS/UI Framework之外,其次就是無痛美化上述的View (HTML Form)。
有用過ASP.NET MVC Scaffold的人都知道,透過EF的Data Context會建立Strongly Typed Views
建立出來這個View可以說是白白豬,什麼Style都沒有。
所以透過Bootstrap Form Builder就可以立即變靚。



2013年2月2日星期六

Download Windows Media Encoder 9 Series x86/x64 Edition

有同事要把AVI影片轉WMV格式,上網找找軟件給他,不負所望,微軟有相關免費軟件 - 就是之前公開免費下載的Expression Encoder 4
可能介面上的不習慣,同事說很複雜...

找另一個叫Windows Media Encoder,已經是十年前的出品,
似乎在Windows Vista上有點問題,不過很簡單易用,我試過一般工作,在Windows 7下工作正常。
32Bit版本,微軟官方依然有提供下載
但64Bit版本,很奇怪只有日文版,若你切換至英文版本,會出現找不到網頁錯誤。

幸好最後都找到了官方的64bit版本




整理一下連結方便日後使用 :

Windows Media Encoder 9
繁體中文 :
32Bit : http://download.microsoft.com/download/b/c/f/bcf48ad9-111c-4af8-8d81-6a9e117e1a2b/WMEncoder.exe

簡體中文 :
32Bit : http://download.microsoft.com/download/e/7/8/e78fc640-aa19-4c00-81c3-e797b2998e1a/WMEncoder.exe

English -
32Bit : http://download.microsoft.com/download/8/1/f/81f9402f-efdd-439d-b2a4-089563199d47/WMEncoder.exe
64Bit : http://download.microsoft.com/download/0/5/1/05150d9b-59dd-453c-8483-d618cec12b12/WMEncoder64.exe