很多人一提到Linq就提到操作數據庫什麼的,其實操作數據庫的只是Linq中 的Linq to SQL,Linq本身是一個很大的家族,而且Linq家族極具擴展性。從人 們一提到Linq就把她當作一個ORM這個來看,說明廣大程序員對Linq to SQL期望 值很高,高過其他幾種,對微軟在框架中集成ORM的期望值也很高。從今兒起我 將用幾篇來介紹Linq to SQL。
Linq to SQL的核心庫是 System.Data.Linq.dll(位於C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5目錄下),不 過,System.Core.dll裡的System.Linq是整個Linq的核心。在 System.Data.Linq.dll裡System.Data.Linq命名空間下的DataContext類是Linq to SQL的入口點,可以說Linq to SQL一切奇妙之處都來源如此。通過 DataContxt我們可以獲取Table對象(這個類和DataContext在同一命名空間下), 你會發現Table竟然是繼承自IEnumerable,那上一篇介紹的那些查詢表達式都可 以應用在Table對象上了,呵呵。
有過使用ORM框架的讀者肯定知道,一 般ORM框架都有個映射,就是將內存中的對象和數據庫表做映射,大名鼎鼎的 NHibernate是使用XML文件做映射的(我們一般將這種映射稱之為無入侵的),還 有ActiveRecord模式一般式在屬性上加Attribute做映射的(一般稱之為侵入式的 )。Linq to SQL也不例外,也需要一個映射,她使用的是侵入式的,所以就需要 一些Attribute,這些Attribute放在System.Data.Linq.Mapping命名空間下。
作為微軟大張旗鼓推出的ORM,Linq to SQL目前卻支持Sql Server,這 個未免有些遺憾(所幸的是對於其他幾種數據庫已經有開源實現了),不過放心, 看看核心庫裡面的命名空間你也許看到了曙光。在System.Data.Linq.dll還有兩 個命名空間:
System.Data.Linq.Provider,這個命名空間是提供一些 Provider模式的接口,由於不同數據庫所需要的SQL語句,一些函數都有一些不 同,但是她們的操作卻都大同小異,所以我們可以抽象一個統一的接口,然後有 各個數據庫的實現(非常奇怪微軟為啥將IProvider接口設置為internal的,難道 他只想他自己一個人干?)。System.Data.Linq.SqlClient命名空間裡放的就是 針對Sql Server的實現了,按照這個結構,支持所有的數據庫都是可以的。
好了,上面對Linq to SQL的一些組件做了一個大致的介紹,下面就稍微 演示一段代碼。
要做一個Linq to SQL的case,首先你必須創建一個映射 類,該類映射到數據庫表。實際上映射類和我們在上一篇所使用的實體類非常相 似(確保對System.Data.Linq.dll的引用,並且對System.Data.Linq.Mapping命 名空間的聲明):
[Table(Name="Users")]
public class User
{
[Column(IsPrimaryKey=true)]
public int UserId { get; set; }
[Column]
public string UserName { get; set; }
[Column]
public string Password { get; set; }
[Column]
public string BlogName { get; set; }
[Column]
public Role Role { get; set; }
}
(看到這裡你也許會命 名什麼叫入侵式了吧,入侵式就是為了達到目的,對代碼做了一些改變,比如這 裡的Table,Column)
User類上面加的Table表示這個類和一個表映射,表 名為Users,注意,如果表名和類名是一樣的,這個Name屬性是無需指定的,在 屬性或共有字段上加Column表示這個屬性和數據庫表裡的字段映射,如果屬性名 和數據庫表字段名一直只需要加個Column就夠了,如果這個屬性在數據庫表裡是 個主鍵,那麼將其IsPrimaryKey設置為true就可以了。
映射建好了,該 是Linq上場的時候了(我們要從數據庫表裡查詢出用戶名以”yu”開 頭的所有用戶):
//我們給定一個數據庫連接字符串實例化一個DataContext對象
DataContext dbContext = new DataContext(connectionString);
dbContext.Log = Console.Out;
//調用DataContext的GetTable方法,獲取一個Table對象
Table<User> users = dbContext.GetTable<User>();
//由於Table繼承自IEnumerable,所以,前面所介紹的那些查詢表達式在這裡也使用了
var result = from user in users
where user.UserName.StartsWith("yu")
select user;
//遍歷結果集
foreach (var u in result)
Console.WriteLine(u.UserName);
很妙吧,沒有了以前重復又重 復的DbCommand,DbConnection代碼,好像C#直接面向數據庫一樣。
在上 面的代碼裡還有一行特殊的代碼:dbContext.Log = Console.Out;,它會將你的 C#查詢表達式最後產生的SQL語句輸出來,這樣就更方便你調試和優化了。
後記
本篇只是對Linq to SQL做一個大致的介紹,使大家對Linq to SQL有個全面的感性認識,在下一節會用大量的實例介紹Linq to SQL的方方 面面。
從這一篇起我會由淺入深的介紹Linq to SQL,如果你已經對Linq to SQL有使用經驗可以輕輕點擊以下你的浏覽器右上角的叉叉。或者你覺得我說 的有地方有錯誤,有誤導大家的嫌疑,煩請不要吝啬你的memory和CPU給我寫個 評語,我將不勝感激。