ADO.NET i LINQ to SQL
LINQ to SQL jest częścią rodziny technologii ADO.NET. Jest on oparty na usługach udostępnianych przez model dostawcy ADO.NET. W związku z tym można mieszać kod LINQ to SQL z istniejącymi aplikacjami ADO.NET i migrować bieżące rozwiązania ADO.NET do LINQ to SQL. Poniższa ilustracja przedstawia ogólny widok relacji.
Połączenia
Istniejące połączenie ADO.NET można podać podczas tworzenia linQ to SQL DataContext. Wszystkie operacje względem DataContext (w tym zapytań) używają tego udostępnionego połączenia. Jeśli połączenie jest już otwarte, linQ to SQL pozostawia je tak samo, jak po zakończeniu z nim.
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()
Zawsze możesz uzyskać dostęp do połączenia i zamknąć go samodzielnie, używając Connection właściwości , jak w poniższym kodzie:
db.Connection.Close();
db.Connection.Close()
Transakcje
Możesz podać swoją DataContext transakcję przy użyciu własnej transakcji bazy danych, gdy aplikacja już zainicjowała transakcję i chcesz DataContext być zaangażowana.
Preferowaną metodą wykonywania transakcji w programie .NET Framework jest użycie TransactionScope obiektu . Korzystając z tego podejścia, można tworzyć transakcje rozproszone, które działają między bazami danych i innymi menedżerami zasobów rezydentów pamięci. Zakresy transakcji wymagają kilku zasobów do uruchomienia. Są one promowane do transakcji rozproszonych tylko wtedy, gdy istnieje wiele połączeń w zakresie transakcji.
using (TransactionScope ts = new TransactionScope())
{
db.SubmitChanges();
ts.Complete();
}
Using ts As New TransactionScope()
db.SubmitChanges()
ts.Complete()
End Using
Nie można użyć tego podejścia dla wszystkich baz danych. Na przykład połączenie sqlClient nie może podwyższyć poziomu transakcji systemowych, gdy działa na serwerze SQL Server 2000. Zamiast tego automatycznie zapisuje się do pełnej, rozproszonej transakcji za każdym razem, gdy widzi używany zakres transakcji.
Polecenia Direct SQL
Czasami mogą wystąpić sytuacje, w których możliwość DataContext wysyłania zapytań lub przesyłania zmian jest niewystarczająca dla wyspecjalizowanego zadania, które chcesz wykonać. W takich okolicznościach można użyć ExecuteQuery metody , aby wydać polecenia SQL do bazy danych i przekonwertować wyniki zapytania na obiekty.
Załóżmy na przykład, że dane klasy Customer
są rozłożone na dwie tabele (customer1 i customer2). Następujące zapytanie zwraca sekwencję Customer
obiektów:
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")
Tak długo, jak nazwy kolumn w wynikach tabelarycznych pasują do właściwości kolumny klasy jednostki, LINQ to SQL tworzy obiekty z dowolnego zapytania SQL.
Parametry
Metoda ExecuteQuery akceptuje parametry. Poniższy kod wykonuje sparametryzowane zapytanie:
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
Uwaga
Parametry są wyrażane w tekście zapytania przy użyciu tej samej notacji curly używanej przez Console.WriteLine()
i String.Format()
. String.Format()
pobiera podane ciąg zapytania i zastępuje parametry nawiasów klamrowych wygenerowanymi nazwami parametrów, takimi jak @p0
, @p1
..., @p(n)
.