摘要:當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 2005、Visual 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 ..........................................  |