ADO.NET 和 LINQ to SQL
LINQ to SQL 是 ADO.NET 技術系列的一部分。 其是以 ADO.NET 提供者模型所提供的服務為基礎。 因此,您可以將 LINQ to SQL 程式碼與現有的 ADO.NET 應用程式混合,並將目前的 ADO.NET 解決方案移轉至 LINQ to SQL。 下圖提供關聯性 (Relationship) 的高層級檢視。
連線
建立 LINQ to SQL DataContext 時,您可以提供現有的 ADO.NET 連線。 針對 DataContext 進行的所有作業 (包含查詢) 都會使用這個提供的連線。 如果連線已開啟,則當您完成時,LINQ to SQL 會讓其保持原樣。
string connString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=c:\northwind.mdf;
Integrated Security=True; Connect Timeout=30; User Instance=True";
SqlConnection nwindConn = new SqlConnection(connString);
nwindConn.Open();
Northwnd interop_db = new Northwnd(nwindConn);
SqlTransaction nwindTxn = nwindConn.BeginTransaction();
try
{
SqlCommand cmd = new SqlCommand(
"UPDATE Products SET QuantityPerUnit = 'single item' WHERE ProductID = 3");
cmd.Connection = nwindConn;
cmd.Transaction = nwindTxn;
cmd.ExecuteNonQuery();
interop_db.Transaction = nwindTxn;
Product prod1 = interop_db.Products
.First(p => p.ProductID == 4);
Product prod2 = interop_db.Products
.First(p => p.ProductID == 5);
prod1.UnitsInStock -= 3;
prod2.UnitsInStock -= 5;
interop_db.SubmitChanges();
nwindTxn.Commit();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Error submitting changes... all changes rolled back.");
}
nwindConn.Close();
Dim conString = "Data Source=.\SQLEXPRESS;AttachDbFilename=c:\northwind.mdf; Integrated Security=True;Connect Timeout=30;User Instance=True"
Dim northwindCon = New SqlConnection(conString)
northwindCon.Open()
Dim db = New Northwnd("...")
Dim northwindTransaction = northwindCon.BeginTransaction()
Try
Dim cmd = New SqlCommand( _
"UPDATE Products SET QuantityPerUnit = 'single item' " & _
"WHERE ProductID = 3")
cmd.Connection = northwindCon
cmd.Transaction = northwindTransaction
cmd.ExecuteNonQuery()
db.Transaction = northwindTransaction
Dim prod1 = (From prod In db.Products _
Where prod.ProductID = 4).First
Dim prod2 = (From prod In db.Products _
Where prod.ProductID = 5).First
prod1.UnitsInStock -= 3
prod2.UnitsInStock -= 5
db.SubmitChanges()
northwindTransaction.Commit()
Catch e As Exception
Console.WriteLine(e.Message)
Console.WriteLine("Error submitting changes... " & _
"all changes rolled back.")
End Try
northwindCon.Close()
您可以一直存取此連接,並且使用 Connection 屬性自行將它關閉,如下列程式碼所示:
db.Connection.Close();
db.Connection.Close()
交易
當您的應用程式已經啟始異動而且您希望您的 DataContext 參與其中時,您可以提供您的 DataContext 與自己的資料庫異動。
與 .NET Framework 進行交易的慣用方法,就是使用 TransactionScope 物件。 使用這個方法,您可以進行適用於所有資料庫和其他常駐記憶體資源管理員的分散式異動。 交易範圍需要少數資源即可開始。 當交易範圍內有多個連線時,才會自行升級至分散式交易。
using (TransactionScope ts = new TransactionScope())
{
db.SubmitChanges();
ts.Complete();
}
Using ts As New TransactionScope()
db.SubmitChanges()
ts.Complete()
End Using
您無法將此方法用於所有資料庫。 例如,SqlClient 連線對 SQL Server 2000 伺服器運作時無法升級系統交易。 反而,每當它看見正在使用的異動範圍時,就會自動參與完整的分散式異動。
直接 SQL 命令
您偶而會碰到 DataContext 查詢或提交變更的能力不足以因應您想執行之特殊工作的情況。 在這些情況下,您可以使用 ExecuteQuery 方法將 SQL 命令發出至資料庫,並將查詢結果轉換為物件。
例如,假設 Customer
類別的資料會分布於兩個資料表 (customer1 和 customer2)。 下列查詢會傳回 Customer
物件的序列:
IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
@"select c1.custid as CustomerID, c2.custName as ContactName
from customer1 as c1, customer2 as c2
where c1.custid = c2.custid"
);
Dim results As IEnumerable(Of Customer) = _
db.ExecuteQuery(Of Customer)( _
"SELECT [c1].custID as CustomerID," & _
"[c2].custName as ContactName" & _
"FROM customer1 AS [c1], customer2 as [c2]" & _
"WHERE [c1].custid = [c2].custid")
只要表格式結果中的資料行名稱符合實體類別的資料行屬性,LINQ to SQL 就會從任何 SQL 查詢建立您的物件。
參數
ExecuteQuery 方法可接受參數。 下列程式碼會執行參數型查詢:
IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
"select contactname from customers where city = {0}",
"London"
);
Dim results As IEnumerable(Of Customer) = _
db.ExecuteQuery(Of Customer)( _
"SELECT contactname FROM customers WHERE city = {0}, 'London'")
End Sub
注意
查詢文字中的參數會使用與 Console.WriteLine()
和 String.Format()
所用的相同大括號標記法加以表示。 String.Format()
會採用您提供的查詢字串,並且以產生的參數名稱 (例如 @p0
、@p1
...、@p(n)
) 替代大括號內的參數。