• Aucun résultat trouvé

Plan. Accès aux données dans le framework.net. ADO.NET Entity Framework LINQ ADO.NET ADO.NET. 1. ADO.NET Mode connecté Mode non connecté

N/A
N/A
Protected

Academic year: 2022

Partager "Plan. Accès aux données dans le framework.net. ADO.NET Entity Framework LINQ ADO.NET ADO.NET. 1. ADO.NET Mode connecté Mode non connecté"

Copied!
9
0
0

Texte intégral

(1)

1 Lionel Seinturier

Accès aux données dans le framework .NET ADO.NET – Entity Framework – LINQ

Lionel Seinturier Université Lille 1

Lionel.Seinturier@univ-lille1.fr

27/3/14

2 Lionel Seinturier

1.  ADO.NET Mode connecté Mode non connecté 2.  Entity Framework 3.  LINQ

ADO.NET

ActiveX Data Object .NET (ADO.NET)

API d'accès (local ou distant)

à une source de données : SGBD, tableur, fichier, messagerie, … Fonctionne selon un principe client/serveur (local ou distant)

•  client = le programme (C#, VB, C++, …)

•  serveur = la source de données Principe

•  le programme ouvre une connexion

•  il envoie des requêtes SQL

•  il récupère les résultats

•  ...

•  il ferme la connexion

ADO.NET

ActiveX Data Object .NET (ADO.NET)

•  API d'interaction avec un SGBD

•  nombreuses utilisations

-  sauvegarde de données de manière sûre -  exploration du contenu d'un SGBD -  client/serveur 3 tiers

serveur d'applications

client SGBD

donnée traitement

présentation

ADO.NET

(2)

ADO.NET 5 Lionel Seinturier

Historique

ODBC

RDO DAO

OLE-DB

ADO

ADO.NET

C++

VB

ts langages – API COM évolutions

unification

simplification (+ haut niveau)

framework .NET

ADO.NET 6 Lionel Seinturier

Fournisseur (provider) et connection string

Implémentation de l'API pour un type de sources de données Un provider par type de base de données (SQL Server, MySQL, etc.) Connection string : identifie la source de données à laquelle on se connecte

•  chaîne de caractères

•  liste de couples propriété=valeur

•  format dépend du provider

Exemple : "Server=...;Database=...;"

ADO.NET

Utilisation

L'API ADO.NET est définie dans System.Data

1. Ouverture d'une connexion avec la base test

SqlConnection cx = new SqlConnection("Server=localhost;Database=test;");

cx.Open();

2. Envoi d'une requête SELECT

SqlCommand cmd = new SqlCommand("SELECT * FROM ages",cx);

SqlDataReader reader = cmd.ExecuteReader();

Envoi d'une requête CREATE, INSERT ou UPDATE

SqlCommand cmd =

new SqlCommand("INSERT INTO ages VALUES ('toto',12)",cx);

cmd.ExecuteNonQuery();

ADO.NET

Utilisation de ADO.NET (suite)

3. Récupération du résultat

reader.Read() retourne vrai tant qu'il reste des enregistrements dans le résultat et positionne le curseur sur l'enregistrement suivant

reader.GetString(int column) (ex. : reader.GetString(0) )

retourne la valeur de la colonne 0 de type String de l enregistrement courant

GetInt32, GetBoolean, GetByte, GetDouble, GetFloat

idem pour des colonnes de type int, boolean, byte, double ou float

while( reader.Read() ) {

String nom = reader.GetString(0);

int age = reader.GetInt32(1);

Console.WriteLine( nom + " a " + age + " ans" );

}

(3)

ADO.NET 9 Lionel Seinturier using System.Data;

using System.Data.SqlClient;

public class TestADONet {

public static void Main( String[] args ) { SqlConnection cx =

new SqlConnection("Server=localhost;Database=test;");

cx.Open();

SqlCommand cmd = new SqlCommand("SELECT * FROM ages",cx);

SqlDataReader reader = cmd.ExecuteReader();

while (reader.Read()) {

string nom = reader.GetString(0);

int age = reader.GetInt32(1);

Console.WriteLine( nom + " a " + age + " ans" );

}

cx.Close();

} }

Utilisation de ADO.NET (code complet)

ADO.NET 10 Lionel Seinturier

Types de requêtes SQL

•  "normale"

-  interprétée à chaque exécution

•  précompilée -  paramétrable

-  préparée pour être exécutée plusieurs fois -  gérée par le programme

•  procédure stockée -  paramétrable

-  écrite dans le langage interne du SGBD (ex SQL Server Transac-SQL) -  gérée par le SGBD

+ masque schéma base - langage propriétaire (- évolution)

+ meilleures perf - risque de mélange

+ validées par rapport schéma base logiques traitement/donnée

ADO.NET

Requêtes SQL précompilées

1. Possibilité de définition de 1 ou +sieurs paramètres ! caractères ? SqlCommand cmd = new SqlCommand

("SELECT * FROM ages WHERE nom=? AND age>?",cx);

2. Valeurs des paramètres ajoutés à la commande

cmd.Parameters.Add(new Parameter("Bob"),cx);

cmd.Parameters.Add(new Parameter(Convert.ToInt32(5)),cx);

• new Parameter( string name, object value )

•  paramètres ajoutés dans l'ordre de leur définition dans la requête

• name non significatif dans ce contexte (voir procédure stockée) 3. Exécution de la requête

SqlDataReader reader = cmd.ExecuteReader();

...

ADO.NET

Procédures stockées

Exemple de procédure stockée Transact-SQL (SQL Server)

CREATE PROCEDURE [pubs].[GetRange]

@age int AS

SELECT nom FROM ages WHERE age < @age GO

Le code d appel de la procédure

SqlCommand cmd = new SqlCommand("GetRange",cx);

cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add( new Parameter("age",Convert.ToInt32(5) );

SqlDataReader reader = cmd.ExecuteReader();

...

(4)

ADO.NET 13 Lionel Seinturier

déclaration du début de la transaction validation de la transaction

Transactions

Groupes de requêtes devant être exécutés de façon indivisible La transaction doit être

-  validée (commit) ! les résultats ne sont visibles qu'à partir de ce moment -  ou annulée (rollback)

SqlCommand cmd1 = new SqlCommand("INSERT INTO ages VALUES ('Pierre',12)",cx);

SqlCommand cmd2 = new SqlCommand("UPDATE ages SET age=15 WHERE nom='Joe'",cx);

SqlTransaction trans = cx.BeginTransaction();

cmd1.Transaction = trans;

cmd2.Transaction = trans;

cmd1.ExecuteNonQuery();

cmd2.ExecuteNonQuery();

trans.Commit();

ADO.NET 14 Lionel Seinturier

Transactions

Exemple

CREATE TABLE comptes (nom VARCHAR(30) PRIMARY KEY, solde FLOAT CHECK(solde>=0) );

SqlCommand cmd1, cmd2;

cmd1 = new SqlCommand("UPDATE comptes SET solde=solde+montant WHERE nom='Paul'",cx);

cmd2 = new SqlCommand("UPDATE comptes SET solde=solde-montant WHERE nom='Bob'",cx);

SqlTransaction trans = cx.BeginTransaction();

try {

cmd1.Transaction = trans;

cmd2.Transaction = trans;

cmd1.ExecuteNonQuery();

cmd2.ExecuteNonQuery();

trans.Commit();

}

catch( Exception e ) { trans.Rollback();

}

ADO.NET

Accès aux données en mode déconnecté

•  par défaut c/s connecté vers SGBD +  1 seule copie des données (SGBD) +  mises à jour simples

connecté vs non connecté n messages petite taille vs 1 message grande taille

Déconnecté

•  pouvoir consulter/modifier les données off line

•  économiser les ressources réseaux (connexions moins longues)

•  travailler sur des données en mémoire plutôt que directement sur un SGBD rés

eau

SELECT …

rés eau

SELECT …

ADO.NET

Accès aux données en mode déconnecté

•  datasets : représentation mémoire des données d'un SGBD

SGBD Data

Adapter DataSet

adapter.Fill(dataset) adapter.Update(dataset)

DataAdapter : gère liaison mémoire (DataSet) – SGBD

!  contient les requêtes SQL (select, update, insert) associées aux données

(5)

ADO.NET 17 Lionel Seinturier

DataSet

Un DataSet contient

•  des DataTable données sous forme de table -  des DataColumn

-  nom, type, propriétés (autoincrement, unique, readonly, maxlength, …), … -  des DataRow

-  valeurs -  des DataConstraint

•  des DataRelation relation entre 2 DataTable

•  une DefaultView Un DataSet peut être

•  consulté

•  modifié (valeurs, lignes) ! mise à jour BD lors de Update()

•  sauvegardé/chargé en XML

ADO.NET 18 Lionel Seinturier

Exemple d'utilisation d'un DataSet

SqlConnection cx = new SqlConnection("Server=localhost;Database=pubs;");

cx.Open();

SqlDataAdapter adapter = new SqlDataAdapter();

adapter.SelectCommand = new SqlCommand("SELECT * FROM comptes",cx);

DbCommandBuilder builder = new SqlCommandBuilder(adapter);

DataSet dataset = new DataSet();

adapter.Fill(dataset);

cx.Close();

for( int i=0 ; i<dataset.Tables.Count ; i++ ) { DataTable table = dataset.Tables[i];

DataColumnCollection columns = table.Columns;

for( int j=0 ; j<table.Rows.Count ; j++ ) { DataRow row = table.Rows[j];

Console.WriteLine("Row "+j+": "+row["nom"]+" "+row["solde"]);

} }

ADO.NET

Mise à jour d'un DataSet

Modification d'une valeur

table.Rows[0][0] = "Bill";

adapter.Update(dataset);

Ajout d'une ligne

DataRow myDataRow = table.NewRow();

myDataRow["nom"] = "John";

myDataRow["solde"] = 123;

table.Rows.Add(myDataRow);

adapter.Update(dataset);

ADO.NET

DataView

Vue (pas de copie des données) sur une Datatable

•  séléction

•  tri

Mise à jour données dans la vue = maj des données dans la DataTable

DataView view = new DataView(table);

view.RowFilter = "nom='Bob'"; // sélection de(s) Bob for( int i=0 ; i < view.Count ; i++ ) {

view.Delete(i); // suppression aussi dans la DataTable }

view.Sort = "nom, age DESC"; // d'abord pas nom puis par age décroissant

Expression de sélection "à la SQL"

-  opérateur LIKE nom LIKE '*ob*'

-  fonctions sum, avg, count, min, max

(6)

ADO.NET 21 Lionel Seinturier

Comparaison ADO.NET - JDBC

ADO.NET JDBC

c/s oui oui

accès provider driver

désignation Server=… jdbc:mysql://…

initialisation new … Class.forName("…")

connexion Open() DriverManager.getConnection

commande …Command Statement/PreparedStatement/CallableState curseur résultat …DataReader ResultSet

curs. multi-dir non oui

curs. maj non oui

deconnecté DataSet RowSet (JDBC 3.0)

transaction cx.BeginTransaction() cx.setAutoCommit(false) trans.Commit() cx.commit()

trans.Rollback() cx.rollback()

≠ niv. isolation oui oui

ADO.NET 22 Lionel Seinturier

Comparaison ADO.NET - JDBC

ADO.NET JDBC

méta-données oui oui

batch non oui

pool de cx oui (provider) oui (JNDI)

Plan

1.  ADO.NET Mode connecté Mode non connecté 2.  Entity Framework 3.  LINQ

Entity Framework

Entity Framework (EF)

Mapping objet relationnel

•  mise en correspondance d'objets (C#, VB, etc.) et SGBD Avantages (par rapport à ADO.NET)

•  typage

•  manipulation d'objets métier (plutôt que SQL) Stockage des données

•  une table par classe

•  données utilisables indifféremment EF, ADO.NET, "directement" en SQL

(7)

Entity Framework 25 Lionel Seinturier

Entity Framework

Principe de base

class Blog {

public int BlogId { get; set; } public string Name { get; set; } }

Notion de contexte pour faire le lien entre objets et SGBD

using System.Data.Entity;

class BlogContext : DbContext { DbSet<Blog> Blogs { get; set; } }

Utilisation

var db = new BlockContext();

var blog = new Blog { BlogId=1; Name=".NET Blog"; };

db.Blogs.Add( blog );

db.SaveChanges(); Stockage

•  base : <nom projet VSudio>.BlogContext

•  table : Blogs

Entity Framework 26 Lionel Seinturier

Entity Framework

Relations entre tables

class Blog {

public int BlogId { get; set; } public string Name { get; set; }

public virtual List<Post> Posts { get; set; } }

class Post {

public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual Blog Blog { get; set; } }

•  relations 1-1, 1-n ou n-m

• virtual = chargement des données uniquement si accédées

Entity Framework

Annotations

Précisent la mise en correspondance objet – relationnel

•  redéfinissent les noms par défaut pour les tables, colonnes

•  renseignent les informations liées aux clés

•  autres : renseignent types SQL, valeurs auto-générées, index

[Table("Journal")]

class Blog {

[Key] public int BlogId { get; set; }

[Column="TitreDuJournal"] public string Name { get; set; } public virtual List<Post> Posts { get; set; }}

class Post {

[Key] public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual Blog Blog { get; set; }

[ForeignKey("BlogId"] public int BlogId {get; set; }}

Entity Framework

Recherches

•  à partir de clé primaire

•  à partir d'une fonction de filtrage

var blog = db.Blogs.find(3);

// null si la clé 3 n'existe pas

var blogs = db.Blogs.Where( b => b.Name=="Bob" );

// résultat de type collection

(8)

Entity Framework 29 Lionel Seinturier

Entity Framework

Modifications

•  ajouts, modifications, suppressions

•  SaveChange() pour prendre en compte modifications (une ou plusieurs)

var blog = new Blog { BlogId=1; Name=".NET Blog"; };

db.Blogs.Add( blog );

db.SaveChanges();

var blog = db.Blogs.find(3);

blog.Name = "John Doe";

db.SaveChanges();

var blog = db.Blogs.find(3);

db.Blogs.Remove( blog );

db.SaveChanges();

30 Lionel Seinturier

Plan

1.  ADO.NET Mode connecté Mode non connecté 2.  Entity Framework 3.  LINQ

LINQ

LINQ (Language INTegrated Query)

Langage de requêtage SQL intégré au langage de programmation (C#, VB, …) Nouveaux mots-clés

•  from : variable d'itération

•  in : collection sur laquelle s'effectue l'itération

•  where : condition de sélection de l'élément courant

•  select : valeur à sélectionner

int[] tab = new int[]{ 6, 3, 1, 2, 5, 4, 6 };

IEnumerable<int> pairs = from number in tab where number % 2 == 0 select number;

foreach(int i in pairs) { ... }

LINQ

LINQ (Language INTegrated Query)

Collections

var people = new List<User>() {

new User { Name = "Bob", Age = 24, Tel = "06" }, new User { Name = "Anne", Age = 26, Tel = "07" } };

var persons = from p in people

where p.Age > 25 && p.Name.StartsWith("A") select p;

Type des données retournées (classe anonyme)

var persons = from p in people

select new { p.Nom, p.Tel };

(9)

LINQ 33 Lionel Seinturier

LINQ

LINQ (Language INTegrated Query)

Jointures

var addresses = new List<Address>() {

new User { Name = "Bob", Ville = "Lille" }, new User { Name = "Pat", Ville = "Paris" } };

var knownAdresses = from p in people from a in addresses where p.Name == a.Name select p.Name;

LINQ 34 Lionel Seinturier

LINQ

LINQ (Language INTegrated Query)

Tri et regroupement

var persons = from p in people orderby p.Name, p.Age select p;

var knownAdresses = from p in people from a in addresses where p.Name == a.Name group p by p.Ville select p.Name;

LINQ

LINQ (Language INTegrated Query)

Opérateurs

•  OfType<T>

•  Min, Max, Sum, Average

object[] values = { 1, "Tom", 'T', 12.5, 3, true, 20 };

var results = values.OfType<int>();

foreach(int i in results) { Console.WriteLine(i); } int[] IntegerValues = { 0, 2, 5, 6, 7 };

int max = IntegerValues.Max();

int min = IntegerValues.Min();

int sum = IntegerValues.Sum();

double average = IntegerValues.Average();

LINQ

LINQ (Language INTegrated Query)

Opérateurs

•  Where(λ)

•  Count(λ)

•  ToArray, ToList

var values = new object[] { 1, "Tom", 'T', 12.5, 3, true, 20 };

var val = values.Where( v => v.ToString().Length >= 3 );

int i = values.Count( v => v.ToString().Length >= 3 );

object[] array = values.ToArray();

List<object> list = array.ToList();

Références

Documents relatifs

Vous avez reçu un mel vous indiquant que, pour accéder à vos documents de rémunérations, vous devez confirmer votre identité lors de votre connexion à l'ENSAP. → Munissez-vous

This study investigated whether spatial density-dependent mortality in 1987 translated into temporal density- dependent mortality of experimental gypsy moth populations created

[r]

Point de vue d’un constructeur et projets (Denis Darmouni, Renault) Point de vue d’un constructeur et projets (Frédéric Lassara, PSA) Point de vue d’un constructeur et projets

• Le véhicule réagit au variations de l’environnement dans sa voie (suivi de voie / régulation de vitesse). • Démonstrateur technologique, associant automatisation

La MDEM s’engage dans la mise en œuvre opérationnelle du Campus Connecté Métropole Aix-Marseille Provence, pour apporter un soutien en ingénierie tout au long

Dans le mode de fonctionnement option variateur (activable depuis l'App), cet interrupteur fonctionne uniquement avec les ampoules à intensité variable (identifiables grâce au

Lecture de la réponse GET sous forme de chaîne à l'aide de System.Net.HttpWebRequest 49 Lecture de la réponse GET sous forme de chaîne à l'aide de System.Net.WebClient 49 Lecture de