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 會讓它保持原樣。
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()
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();
您可以一直存取此連接,並且使用 Connection 屬性自行將它關閉,如下列程式碼所示:
db.Connection.Close()
db.Connection.Close();
異動
當您的應用程式已經啟始交易而且您希望您的 DataContext 參與其中時,您可以提供您的 DataContext 與自己的資料庫交易。
與 .NET Framework 進行交易的慣用方法,就是使用 TransactionScope 物件。 使用這個方法,您可以進行適用於所有資料庫和其他常駐記憶體資源管理員的分散式交易。 交易範圍需要少數資源即可開始。 當交易範圍內有多個連線時,才會自行升級至分散式交易。
Using ts As New TransactionScope()
db.SubmitChanges()
ts.Complete()
End Using
using (TransactionScope ts = new TransactionScope())
{
db.SubmitChanges();
ts.Complete();
}
您無法將此方法用於所有資料庫。 例如,SqlClient 連接對 SQL Server 2000 伺服器運作時並無法升級系統交易。 反而,每當它看見正在使用的交易範圍時,就會自動參與完整的分散式交易。
直接 SQL 命令
您偶而會碰到 DataContext 查詢或提交變更的能力不足以因應您想執行之特殊工作的情況。 在這些情況下,您可以使用 ExecuteQuery 方法將 SQL 命令發出至資料庫,並將查詢結果轉換為物件。
例如,假設 Customer 類別的資料會分布於兩個資料表 (customer1 和 customer2)。 下列查詢會傳回 Customer 物件的序列:
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")
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"
);
只要表格式結果中的資料行名稱符合實體 (Entity) 類別的資料行屬性,LINQ to SQL 就會從任何 SQL 查詢建立物件。
參數
ExecuteQuery 方法可接受參數。 下列程式碼會執行參數型查詢:
Dim results As IEnumerable(Of Customer) = _
db.ExecuteQuery(Of Customer)( _
"SELECT contactname FROM customers WHERE city = {0}, 'London'")
End Sub
IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
"select contactname from customers where city = {0}",
"London"
);
注意事項 |
---|
查詢文字中的參數會使用與 Console.WriteLine() 和 String.Format() 所用的相同大括號標記法加以表示。String.Format() 會採用您提供的查詢字串,並且以產生的參數名稱 (例如 @p0、@p1 ...、@p(n)) 替代大括號內的參數。 |
請參閱
工作
HOW TO:重複使用 ADO.NET 命令和 DataContext 之間的連接 (LINQ to SQL)