當VS2005 遇上 LINQ

摘要:當VS2005 遇上 LINQ

VS2005 遇上 LINQ
 
/黃忠成
 
 
 【極意之道-次世代 .NET Framework 3.5 資料庫開發聖典】(好長的書名,我該取個匿稱嗎?哈)一書第三章中,有下面這段敘述:
任何支援.NET Framework 2.0的程式語言都能夠叫用LINQ所提供的查詢函式,也就是說能使用C# 2.0來呼叫LINQ Framework
書中列出一小段程式碼,證明事實上只要是C# 2.0,就能夠使用LINQ所提供的查詢函式,前提是電腦中必須安裝.NET Framework 3.5
 那好,什麼時候我們會需要這種寫法呢?想像一下,你可以利用LINQ查詢函式來做什麼?你可以將兩個陣列Join起來、排序、Group、查詢,你也可以將兩個XML檔案Join起來,甚至可以將兩個DataTable Join起來,哦!這段敘述是否挑到你最敏感的那條神經了呢?
  不過,說歸說,做歸做,如果在.NET Framework 2.0中叫用LINQ,能得到什麼好處呢?很明顯的,你原本的專案不需要做大幅度的升級,你不需要裝Visual Studio 2008,你只需安裝.NET Framework 3.5,然後加入對System.Core的參考,就能得到LINQ查詢函式的火力,再加入System.Xml.Linq的參考,就能得到LINQ To XML查詢函式,加入System.Data.DataSetExtensions的參考,就能將兩個DataTable Join起來。
 但,有了這些好處,事情真的會比較簡單嗎?那得視情況而定,在沒有LINQ Expression支援下使用LINQ查詢函式,有時會將事情變的複雜,換句話說,程式碼可能變多了。不過,大部份情況下,我相信使用LINQ查詢函式會把程式碼縮短,畢竟,查詢演算法是內建在LINQ中了。
static void DemoLinq()
{
            string[] list = new string[] { "code6421", "tom", "david", "cathy" };
            IEnumerable<string> result = Enumerable.Where<string>(list,
                             delegate(string item)
                             {
                                 return item == "tom";
                             });
            Console.WriteLine(Enumerable.FirstOrDefault(result));
}
上面這段程式碼可以運行於Visual Studio 2005Visual Studio 2008,如你使用Visual Studio 2005,請先安裝.NET Framework 3.5,然後於專案中添加對System.Core的參考(DLL位於Program Files\ Reference Assemblies\Microsoft\Framework\3.5),完成後編譯程式,你便達到於C#,Visual Studio 2005中使用LINQ的目的。
 
Join 2 DataTables
 
 我想有許多寫Windows Form程式的人,都曾經對於如何Join兩個DataTable困擾過,事實上這很簡單,只要建另一個DataTable,一個蘿蔔一個坑的填即可。
 不過有了LINQ To DataSet,一切都變的簡單且直覺,但!缺少了LINQ Expression的C# 2.0,只憑LINQ 查詢函式來做,可以把這件事變簡單嗎?
using System.Data.SqlClient;
........
static IEnumerable<JoinData> JoinTables()
{
            using (SqlConnection conn = new SqlConnection(
"Data Source=JEFFRAY;Initial Catalog=Northwind;Integrated Security=True"))
{
                SqlDataAdapter adapter1 = new SqlDataAdapter("SELECT * FROM Customers", conn);
                SqlDataAdapter adapter2 = new SqlDataAdapter("SELECT * FROM Orders", conn);
                DataTable dt1 = new DataTable("Customers");
                DataTable dt2 = new DataTable("Orders");
                adapter1.Fill(dt1);
                adapter2.Fill(dt2);
 
                return Enumerable.Join<DataRow,DataRow,string,JoinData>(
                         DataTableExtensions.AsEnumerable(dt2),
                         DataTableExtensions.AsEnumerable(dt1),
                            delegate(DataRow s1)
                            {
                               return s1.IsNull("CustomerID") ?
                                      null : (string)s1["CustomerID"];
                            },
                            delegate(DataRow s2)
                            {
                               return s2.IsNull("CustomerID") ? null :
                                   (string)s2["CustomerID"];
                            },
                            delegate(DataRow s1,DataRow s2)
                            {
                                JoinData result = new JoinData();
                                  result.OrderID = s1.IsNull("OrderID") ? -1 :
                                         (int)s1["OrderID"];
                                result.CompanyName = s2.IsNull("CompanyName") ?
                                  string.Empty : (string)s2["CompanyName"];
                                   return result;
                             });
             }
 }
 
.........
public class JoinData
{
        private int _orderID;
        private string _companyName;
        public int OrderID
        {
            get
            {
                return _orderID;
            }
            set
            {
                _orderID = value;
            }
        }
 
        public string CompanyName
        {
            get
            {
                return _companyName;
            }
            set
            {
                _companyName = value;
            }
        }
}
這個程式需要引用System.Data.DataSetExtnesions.DLL,她與System.Core位於同一目錄下,JoinTables的函式傳回值頃印結果如下:
10779,Morgenstern Gesundkost
10780,LILA-Supermercado
10781,Wartian Herkku
10782,Cactus Comidas para llevar
10783,Hanari Carnes
10784,Magazzini Alimentari Riuniti
10785,GROSELLA-Restaurante
10786,Queen Cozinha
10787,La maison d'Asie
10788,QUICK-Stop
10789,Folies gourmandes
10790,Gourmet Lanchonetes
10791,Frankenversand
10792,Wolski Zajazd
10793,Around the Horn
10794,Que Delicia
10795,Ernst Handel
10796,HILARION-Abastos
10797,Drachenblut Delikatessen
10798,Island Trading
10799,Koniglich Essen
10800,Seven Seas Imports
..........................................
 

歡迎光臨C# 2.0與LINQ的世界。