ADO.NET および LINQ to SQL
LINQ to SQL は、ADO.NET テクノロジ ファミリの一部です。 ADO.NET プロバイダー モデルによって提供されるサービスが基になっています。 したがって、LINQ to SQL のコードを既存の ADO.NET アプリケーションと混在させることができ、現在の ADO.NET ソリューションを LINQ to SQL に移行できます。 次の図は、この関係を高いレベルから見たものです。
つながり
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
クラスのデータが 2 つのテーブル (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
Note
パラメーターは、Console.WriteLine()
および String.Format()
で使用されるものと同じ中かっこ表記でクエリ テキストに表現されます。 String.Format()
は、指定されたクエリ文字列を受け取り、中かっこで囲まれたパラメーターを、@p0
、@p1
…、@p(n)
などの、生成されたパラメーター名に置き換えます。