ADO.NET et LINQ to SQL
LINQ to SQL fait partie de la famille de technologies ADO.NET. Elle est basée sur des services fournis par le modèle de fournisseur ADO.NET. Vous pouvez donc mélanger du code LINQ to SQL avec des applications ADO.NET existantes, et migrer des solutions ADO.NET actuelles vers LINQ to SQL. L'illustration suivante fournit une vue d'ensemble de la relation.
Connexions
Vous pouvez fournir une connexion ADO.NET existante lorsque vous créez un DataContext LINQ to SQL. Toutes les opérations sur le DataContext (requêtes incluses) utilisent la connexion fournie. Si la connexion est déjà ouverte, LINQ to SQL la ferme comme si vous aviez terminé.
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()
Vous pouvez toujours accéder à la connexion et la fermer à l'aide de la propriété Connection, comme dans le code suivant :
db.Connection.Close();
db.Connection.Close()
Transactions
Vous pouvez fournir à votre DataContext votre propre transaction de base de données lorsque votre application a déjà initialisé la transaction et que vous souhaitez impliquer votre DataContext.
Il est recommandé d’utiliser l’objet TransactionScope pour les transactions avec .NET Framework. Grâce à cette approche, vous pouvez effectuer des transactions distribuées qui fonctionnent sur les bases de données et d'autres gestionnaires de ressources résidant en mémoire. Les portées de transactions requièrent des ressources pour démarrer. Elles effectuent leur propre promotion en transactions distribuées uniquement lorsque la portée de la transaction comporte plusieurs connexions.
using (TransactionScope ts = new TransactionScope())
{
db.SubmitChanges();
ts.Complete();
}
Using ts As New TransactionScope()
db.SubmitChanges()
ts.Complete()
End Using
Vous ne pouvez pas utiliser cette approche pour toutes les bases de données. Par exemple, la connexion SqlClient ne peut pas effectuer la promotion des transactions système lorsqu’elle fonctionne sur un serveur SQL Server 2000. Elle s’inscrit automatiquement à une transaction distribuée complète à chaque fois qu’elle voit qu’une portée de transaction est utilisée.
Commandes SQL directes
Il peut arriver que la capacité du DataContext en termes d'interrogation ou de soumission de modifications soit insuffisante pour la tâche spécialisée que vous souhaitez effectuer. Dans ce cas, vous pouvez utiliser la méthode ExecuteQuery pour transmettre des commandes SQL à la base de données et convertir les résultats de la requête en objets.
Par exemple, supposons que les données de la classe Customer
sont réparties sur deux tables (customer1 et customer2). La requête suivante retourne une séquence d'objets 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")
Tant que les noms de colonne des résultats sous forme de tableau correspondent aux propriétés des colonnes de votre classe d’entité, LINQ to SQL crée vos objets à partir de n’importe quelle requête SQL.
Paramètres
La méthode ExecuteQuery accepte les paramètres. Le code suivant exécute une requête paramétrée :
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
Notes
Les paramètres sont exprimés dans le texte de requête en utilisant la même notation avec accolades utilisée par Console.WriteLine()
et String.Format()
. String.Format()
utilise la chaîne de requête fournie et substitue les paramètres entre accolades par des noms de paramètre générés tels que @p0
, @p1
…, @p(n)
.