1. 程式人生 > >LINQ to SQL 之DataContext用法

LINQ to SQL 之DataContext用法

DataContext作為LINQ to SQL框架的主入口點,為我們提供了一些方法和屬性,本文用幾個例子說明DataContext幾個典型的應用。

建立和刪除資料庫

CreateDatabase方法用於在伺服器上建立資料庫。
DeleteDatabase方法用於刪除由DataContext連線字串標識的資料庫。

資料庫的名稱有以下方法來定義:
如果資料庫在連線字串中標識,則使用該連線字串的名稱。
如果存在DatabaseAttribute屬性(Attribute),則將其Name屬性(Property)用作資料庫的名稱。
如果連線字串中沒有資料庫標記,並且使用強型別的DataContext,則會檢查與DataContext繼承類名稱相同的資料庫。如果使用弱型別的DataContext,則會引發異常。
如果已通過使用檔名建立了DataContext,則會建立與該檔名相對應的資料庫。

我們首先用實體類描述關係資料庫表和列的結構的屬性。再呼叫DataContext的CreateDatabase方法,LINQ to SQL會用我們的定義的實體類結構來構造一個新的資料庫例項。還可以通過使用 .mdf 檔案或只使用目錄名(取決於連線字串),將 CreateDatabase與SQL Server一起使用。LINQ to SQL使用連線字串來定義要建立的資料庫和作為資料庫建立位置的伺服器。

說了這麼多,用一段例項說明一下吧!

首先,我們新建一個NewCreateDB類用於建立一個名為NewCreateDB.mdf的新資料庫,該資料庫有一個Person表,有三個欄位,分別為PersonID、PersonName、Age。(點選展開程式碼)

 程式碼在這裡展開

接下來的一段程式碼先建立一個數據庫,在呼叫CreateDatabase後,新的資料庫就會存在並且會接受一般的查詢和命令。接著插入一條記錄並且查詢。最後刪除這個資料庫。

 //1.新建一個臨時資料夾來存放新建的資料庫
 string userTempFolder = Environment.GetEnvironmentVariable
 ("SystemDrive") + @"\YJingLee";
 Directory.CreateDirectory(userTempFolder);
 //2.新建資料庫NewCreateDB
 string userMDF = System.IO.Path
.Combine(userTempFolder, @"NewCreateDB.mdf"); string connStr = String.Format(@"Data Source=.\SQLEXPRESS; AttachDbFilename={0};Integrated Security=True; Connect Timeout=30;User Instance=True; Integrated Security = SSPI;", userMDF); NewCreateDB newDB = new NewCreateDB(connStr); newDB.CreateDatabase(); //3.插入資料並查詢 var newRow = new Person { PersonID = 1, PersonName = "YJingLee", Age = 22 }; newDB.Persons.InsertOnSubmit(newRow); newDB.SubmitChanges(); var q = from x in newDB.Persons select x; //4.刪除資料庫 newDB.DeleteDatabase(); //5.刪除臨時目錄 Directory.Delete(userTempFolder);

資料庫驗證

DatabaseExists方法用於嘗試通過使用DataContext中的連線開啟資料庫,如果成功返回true。

下面程式碼說明是否存在Northwind資料庫和NewCreateDB資料庫 。

//檢測Northwind資料庫是否存在
if (db.DatabaseExists())
    Console.WriteLine("Northwind資料庫存在");
else
    Console.WriteLine("Northwind資料庫不存在");
//檢測NewCreateDB資料庫是否存在
string userTempFolder = Environment.GetEnvironmentVariable("Temp");
string userMDF = System.IO.Path.Combine(userTempFolder,
@"NewCreateDB.mdf");
NewCreateDB newDB = new NewCreateDB(userMDF);

if (newDB.DatabaseExists())
    Console.WriteLine("NewCreateDB資料庫存在");
else
    Console.WriteLine("NewCreateDB資料庫不存在");

資料庫更改

SubmitChanges方法計算要插入、更新或刪除的已修改物件的集,並執行相應命令以實現對資料庫的更改。

無論物件做了多少項更改,都只是在更改記憶體中的副本。並未對資料庫中的實際資料做任何更改。直到對DataContext顯式呼叫SubmitChanges,所做的更改才會傳輸到伺服器。呼叫時,DataContext會設法將我們所做的更改轉換為等效的SQL命令。我們也可以使用自己的自定義邏輯來重寫這些操作,但提交順序是由DataContext的一項稱作“更改處理器”的服務來協調的。事件的順序如下:

  1. 當呼叫SubmitChanges時,LINQ to SQL會檢查已知物件的集合以確定新例項是否已附加到它們。如果已附加,這些新例項將新增到被跟蹤物件的集合。
  2. 所有具有掛起更改的物件將按照它們之間的依賴關係排序成一個物件序列。如果一個物件的更改依賴於其他物件,則這個物件將排在其依賴項之後。
  3. 在即將傳輸任何實際更改時,LINQ to SQL會啟動一個事務來封裝由各條命令組成的系列。
  4. 對物件的更改會逐個轉換為SQL命令,然後傳送到伺服器。

如果資料庫檢測到任何錯誤,都會造成提交程序停止並引發異常。將回滾對資料庫的所有更改,就像未進行過提交一樣。DataContext 仍具有所有更改的完整記錄。

下面程式碼說明的是在資料庫中查詢CustomerID為ALFKI的顧客,然後修改其公司名稱,第一次更新並呼叫SubmitChanges()方法,第二次更新了資料但並未呼叫SubmitChanges()方法。

//查詢
Customer cust = db.Customers.First(c => c.CustomerID == "ALFKI");
//更新資料並呼叫SubmitChanges()方法
cust.CompanyName = "YJingLee's Blog";
db.SubmitChanges();
//更新資料沒有呼叫SubmitChanges()方法
cust.CompanyName = "http://lyj.cnblogs.com";

動態查詢

使用動態查詢,這個例子用CreateQuery()方法建立一個IQueryable<T>型別表示式輸出查詢的語句。這裡給個例子說明一下。有關動態查詢具體內容,下一篇介紹。

var c1 = Expression.Parameter(typeof(Customer), "c");
PropertyInfo City = typeof(Customer).GetProperty("City");

var pred = Expression.Lambda<Func<Customer, bool>>(
    Expression.Equal(
    Expression.Property(c1, City),
    Expression.Constant("Seattle")
   ), c1
);
IQueryable custs = db.Customers;
Expression expr = Expression.Call(typeof(Queryable), "Where",
    new Type[] { custs.ElementType }, custs.Expression, pred);
IQueryable<Customer> q = db.Customers.AsQueryable().
Provider.CreateQuery<Customer>(expr);

日誌

Log屬性用於將SQL查詢或命令列印到TextReader。此方法對了解 LINQ to SQL 功能和除錯特定的問題可能很有用。

下面的示例使用Log屬性在SQL程式碼執行前在控制檯視窗中顯示此程式碼。我們可以將此屬性與查詢、插入、更新和刪除命令一起使用。

//關閉日誌功能
//db.Log = null;
//使用日誌功能:日誌輸出到控制檯視窗
db.Log = Console.Out;
var q = from c in db.Customers
        where c.City == "London"
        select c;
//日誌輸出到檔案
StreamWriter sw = new StreamWriter(Server.MapPath("log.txt"), true);
db.Log = sw;
var q = from c in db.Customers
        where c.City == "London"
        select c;
sw.Close();