Udostępnij za pośrednictwem


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.

LINQ to SQL and ADO.NET

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).

Zobacz też