ADO.NET und LINQ to SQL

Aktualisiert: November 2007

LINQ to SQL ist Teil der ADO.NET-Technologiefamilie. Es basiert auf den vom ADO.NET-Anbietermodell bereitgestellten Diensten. Sie können deshalb LINQ to SQL-Code mit vorhandenen ADO.NET-Anwendungen kombinieren und aktuelle ADO.NET-Lösungen zu LINQ to SQL migrieren. Die folgende Abbildung stellt eine allgemeine Ansicht der Beziehung dar.

LINQ to SQL und ADO.NET

Verbindungen

Sie können eine vorhandene ADO.NET-Verbindung angeben, wenn Sie einen LINQ to SQL DataContext erstellen. Alle Operationen mit dem DataContext (einschließlich Abfragen) verwenden diese bereitgestellte Verbindung. Ist die Verbindung bereits geöffnet, lässt LINQ to SQL sie nach deren Verwendung unverändert.

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();

Sie können stets auf die Verbindung zugreifen und diese selbst beenden, indem Sie die Connection-Eigenschaft wie im folgenden Code verwenden:

db.Connection.Close()
db.Connection.Close(); 

Transaktionen

Sie können Ihren DataContext mit Ihrer eigenen Datenbanktransaktion ergänzen, wenn Ihre Anwendung die Transaktion bereits initiiert hat und Sie möchten, dass der DataContext berücksichtigt wird.

Die bevorzugte Methode für Transaktionen mit .NET Framework ist die Verwendung des TransactionScope-Objekts. Mithilfe dieses Ansatzes können Sie verteilte Transaktionen erstellen, die über Datenbanken hinweg und in Verbindung mit anderen speicherresidenten Ressourcen-Managern funktionieren. Transaktionsbereiche erfordern zunächst wenige Ressourcen. Sie stufen sich selbst nur dann zu verteilten Transaktionen hoch, wenn mehrere Verbindungen innerhalb des Transaktionsbereichs vorliegen.

Using ts As New TransactionScope()
    db.SubmitChanges()
    ts.Complete()
End Using
using (TransactionScope ts = new TransactionScope())
{
    db.SubmitChanges();
    ts.Complete();
}

Sie können diesen Ansatz nicht für alle Datenbanken verwenden. Beispielsweise kann die SqlClient-Verbindung keine Systemtransaktionen hochstufen, wenn ein SQL Server 2000-Server verwendet wird. Stattdessen wird automatisch eine vollständige, verteilte Transaktion erzeugt, wenn erkannt wird, dass ein Transaktionsbereich genutzt wird.

Direkte SQL-Befehle

Es kann zu Situationen kommen, in denen die Möglichkeiten des DataContext zum Abfragen oder zum Übergeben von Änderungen für die spezifische Aufgabe nicht ausreichen. In diesen Fällen können Sie die ExecuteQuery-Methode verwenden, um SQL-Befehle an die Datenbank zu übergeben und die Abfrageergebnisse in Objekte zu konvertieren.

Nehmen Sie zum Beispiel an, dass die Daten der Customer-Klasse auf zwei Tabellen (customer1 und customer2) verteilt sind. Die folgende Abfrage gibt eine Sequenz von Customer-Objekten zurück:

    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"
);

Sofern die Spaltennamen im tabellarischen Ergebnis den Spalteneigenschaften Ihrer Entitätsklasse entsprechen, erzeugt LINQ to SQL Ihre Objekte aus einer beliebigen SQL-Abfrage.

Parameter

Die ExecuteQuery-Methode akzeptiert Parameter. Der folgende Code führt eine parametrisierte Abfrage aus:

    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"
);
Hinweis:

Parameter werden im Abfragetext mit der gleichen verschachtelten Schreibweise wie in Console.WriteLine() und String.Format() ausgedrückt. String.Format() übernimmt Ihre Abfragezeichenfolge und ersetzt die verschachtelten Parameter durch erzeugte Parameternamen wie @p0, @p1 …, @p(n).

Siehe auch

Aufgaben

Gewusst wie: Wiederverwenden einer Verbindung zwischen einem ADO.NET-Befehl und einem DataContext (LINQ to SQL)

Weitere Ressourcen

Hintergrundinformationen (LINQ to SQL)