Vous êtes sur la page 1sur 90

Technicien en Techniques de Développement Informatique

Guide des Cours

Module 09 :

Développement et déploiement d’une application


Client / Serveur

Linq To SQL,

Connecté

et

Déconnecté.

XML et DOM

En CSharp

Hamid Mask
Formateur en TDI

Janvier 2014

1 / 90
Linq To SQL
I - Mise à jour, recherche et navigation : méthodes diverses.
1 - Mise à jour de la table Client avec la classe BindingSource :

La classe BindingSource (de type collection) est très intéressante car elle
possède un pointeur de ligne qui permet de se déplacer dans un objet
(collection) BindingSource.
Elle possède aussi des méthodes Move pour la navigation.
VenteDataContext dc = new VenteDataContext();
BindingSource ClientBS = new BindingSource();
Client ClientActuel;

ClientBS.DataSource = dc.Client;
Après cette affectation, le BindingSource ClientBS possède maintenant la même
structure que la table Client. De plus, il y’a maintenant une liaison dynamique entre eux
dans le sens ClientBS vers la table Client. Cela signifie que tout ce qui se passe dans
ClientBS se passe aussi dans la table Client. L’inverse n’est pas vrai.

a) Ajout dans la table Client :

ClientBS.AddNew();

ClientActuel = (Client)ClientBS.Current; // Mise du client courant dans la


variable // ClientActuel

ClientActuel.CodeCl = TxtCodeCl.Text;
ClientActuel.Nom = TxtNom.Text;
ClientActuel.Ville = TxtVille.Text;
ClientBS.EndEdit();  Enregistre dans ClientBS et la table Client

dc.SubmitChanges();  Enregistre dans la Base de Données

b) Modification d’un Client :

ClientActuel = (Client)ClientBS.Current;
ClientActuel.CodeCl = TxtCodeCl.Text;
ClientActuel.Nom = TxtNom.Text;
ClientActuel.Ville = TxtVille.Text;
ClientBS.EndEdit();  Enregistre dans ClientBS et la table Client

dc.SubmitChanges();  Enregistre dans la Base de Données

c) Suppression d’un Client :

ClientBS.RemoveCurrent();  Suppression dans ClientBS et la table Client


dc.SubmitChanges();  Suppression dans la Base de Données

2 / 90
2 - Recherche et navigation avec la classe BindingSource :

a) Navigation :

ClientBS.MoveFirst ();
ClientBS.MoveNext ();
ClientBS.MovePrevious();
ClientBS.MoveLast();

b) Recherche :

La methode Find() n’est pas prise en charge avec Linq To SQL !

Syntaxe :
ClientBS. Find(“CodeCl”, TxtRechercher.Text);

Il ne reste qu’à utiliser une requête Linq To SQL :

Pour rechercher un client selon CodeCl :


var Cl = (from cl in dc.Client
where cl.CodeCl == TxtRechercheCl.Text
select cl).First();

Pour rechercher un client selon le CodeCl, le Nom ou la Ville :

var Cl = (from cl in dc.Client


where c.CodeCl == TxtRechercheCl.Text || cl.Nom == TxtRechercheCl.Text
|| cl.Ville == TxtRechercheCl.Text
select cl).First();

Et pointer le client trouvé :


ClientBS.Position = ClientBS.IndexOf(cl);

c) Affichage :

Pour afficher les données dans le formulaire, on utilise la procédure suivante :

public void Afficher()


{
ClientActuel = (Client) ClientBS.Current;
TxtCodeCl.Text = ClientActuel.CodeCl;
TxtNom.Text = ClientActuel.Nom;
TxtVille.Text = ClientActuel.Ville;
}

3 / 90
Représentation des classes DataContext et BindingSource :

DataContext BindingSource
- Current : Client (exemple)
- Connection - Position : int
- DataSource : Collection
- SubmitChanges() - AddNew()
- CreateDatabase() - EndEdit()
- DatabaseExists() - RemoveCurrent()
- ExecuteCommand() - Find() : non prise en charge
- ExecuteQuery() - MoveFirst()
- ExecuteQuery<>() - MoveNext()
- MovePrévious()
- MoveLast()

2 - Avec BindingSource et Liaison automatique

Les TextBoxs du formulaire peuvent être liés aux colonnes du BindingSource, par
le biais des propriétés DataBindings de la façon suivante :

TxtCodeCl.DataBindings.Add("Text", ClientBS, "CodeCl");


TxtNom.DataBindings.Add("Text", ClientBS, "Nom");
TxtVille.DataBindings.Add("Text", ClientBS, "Ville");

Et on n’a plus besoin d’une procédure Afficher() pour afficher les lignes du
BindingSource dans les TextBoxs du formulaire.

3 - Mise à jour direct dans la table Client (sans BindingSource)

I - Principes de la mise à jour en Linq To SQL :

a) Ajout dans la table Client :

Client cl = new Client();


cl.CodeCl = "Cl20";
cl.Nom = "Filali";
cl.Ville = "Fès";

dc.Client.InsertOnSubmit(cl) ;
dc.SubmitChanges();

b) Suppression d’un Client :

Rechercher un objet Client cl.


4 / 90
dc.Client.DeleteOnSubmit(cl) ;
dc.SubmitChanges();

c) Modification d’un Client :

Rechercher un objet Client cl.


cl.Nom = "Sqalli";
cl.Ville = "Casa";
dc.SubmitChanges();

d) Ajout par le biais d’une collection :

List<Client> ListClient = new List<Client>() ;


Client cl1 = new Client();
cl1.CodeCl = "Cl20";
cl1.Nom = "Filali";
cl1.Ville = "Fès";
ListClient. Add(cl1);

Client cl2 = new Client();


cl2.CodeCl = "Cl21";
cl2.Nom = "Rolam";
cl2.Ville = "Casa";
ListClient. Add(cl2);

dc.Client.InsertAllOnSubmit(ListClient) ;
dc.SubmitChanges();

e) Suppression par le biais d’une collection :

Mettre les clients à supprimer dans une collection ListClient.


ListClient. Add(cl1);
ListClient. Add(cl2);
dc.Client.DeleteAllOnSubmit(ListClient) ;
dc.SubmitChanges();

Remarque : Vous pouvez vider la table Client avec :


dc.Client.DeleteAllOnSubmit(dc.Client) ;

Vous pouvez supprimer tous les details d’une commande :


Soit un objet commande c :
dc.Detail.DeleteAllOnSubmit(c.Detail) ;

II – Navigation et recherche :

a) Pour la navigation dans la table Client, on utilisera les méthodes Skip et


Take.

Collection.Skip(p).Take(q);

5 / 90
Permet de soustraire une sous-collection de Collection en
commençant au p ème élément et prenant q éléments.
p = 0,1,2 … et q = 1,2,3 …

Pour naviguer on utilise un compteur p initialisé à 0 :


ClientActuel = dc.Client.Skip(p).Take(1).First();

First() pour prendre le premier élément de la sous-collection.

Formulaire de test des méthodes Skip et Take.

Code C# :

public partial class Test_Skip_Take : Form


{
VenteDataContext dc = new VenteDataContext();

private void Test_Skip_Take_Load(object sender, EventArgs e)


{
dgv2.DataSource = dc.Client;
}

private void Cmd_Skip_Take_Click(object sender, EventArgs e)


{
var Clients = dc.Client.Skip(int.Parse(txt1.Text)).Take(int.Parse(txt2.Text));

dgv1.DataSource = Clients;

}
}

6 / 90
Requêtes Linq To SQL
(Expressions λ (Lambda) et LinqPad)

Clients.Where (c => c.Nom.StartsWith ("a"))

Clients
.Where (c => c.Nom.StartsWith ("A"))
.OrderBy (c => c.Nom)
.Select (c => c.Nom.ToUpper())

7 / 90
Clients
.Where (c => c.Nom.StartsWith ("A"))
.OrderBy (c => c.Nom)
.Select (c => c.Nom.ToUpper())
.Skip (1)
.Take (1)

Clients.Where (c => c.Nom.StartsWith("A"))


.Intersect (
Clients.Where (c => c.Ville == "Fès"))

8 / 90
I – Requêtes Linq appliquées sur les tables du DataContext.

1) TOP (N)

SQL  SELECT TOP (3) CodeCl,Nom,Ville FROM Client

Linq To SQL  var clients = (from cl in dc.Client select cl).Take(3).ToList();

2) TOP (N)

SELECT [t0].[movie_id] AS [Movie_id],


[t0].[title] AS [Title],
[t0].[release_date] AS [Release_date]
FROM [dbo].[movies] AS [t0]
ORDERBY (
SELECT AVG([t1].[rating])
FROM [dbo].[reviews] AS [t1]
WHERE [t1].[movie_id] = [t0].[movie_id]
)

SELECT [t0].[review_id] AS [Review_id],


[t0].[movie_id] AS [Movie_id],
[t0].[summary] AS [Summary],

9 / 90
[t0].[rating] AS [Rating],
[t0].[review] AS [ReviewText],
[t0].[reviewer] AS [Reviewer]
FROM [dbo].[reviews] AS [t0]
WHERE [t0].[movie_id] = @p0

var allMovies =
from movie in ctx.Movies
orderby movie.Reviews.Average(m => m.Rating)
select movie;

foreach (var movie in allMovies)


{
Console.WriteLine(movie.Title);
foreach (var review in movie.Reviews)
{
Console.WriteLine("\t{0}:{1}",
review.Reviewer,
review.Rating);
}
}

3) TOP (N)

4) TOP (N)

5) TOP (N)

10 / 90
Accès à une base de données Sécurisée
(C# et Sécurité SQL Server2012)

I – Sécurité SQL et Mode connecté :

1 – Côté SQL Server :

Créer la connexion Con et l’utilisateur Ali :

Create Login Con


With PassWord = '123',
Default_Database = Vente

Create User Ali


For Login Con
With Default_Schema = dbo

A ce stade, l’utilisateur Ali n’a aucun droit sur la base de données Vente.

2 – Côté C# (Visual Studio) :

 Prenez le formulaire de mise à jour de la table Client en mode connecté.


(Voir TP1 : Gestion Commerciale en mode connecté dans le Guide des TPs).
 Testez-le sans la sécurité. C’est-à-dire avec la chaine de connexion suivante :

string strcon = @"Data Source = FORMATEUR-PC\SQLExpress;


11 / 90
Initial Catalog = Vente; Integrated Security = True ";

Integrated Security = True : veut dire que SQL Server utilisera l’authentification
Windows (Windows Authentication).
Par conséquent, il faudra que le Serveur SQL soit configuré pour l’authentification
Windows.

 Si tout marche bien, passer au mode sécurisé :

La chaine de connexion va changer :

string strcon = @"Data Source = FORMATEUR-PC\SQLExpress;


Initial Catalog = Vente; uid = Con; pwd = '123' ";

Maintenant, il faudra que le Serveur SQL soit configuré pour "SQL Server and Windows
authentication mode".

Parenthèse :
Si ce n’est pas le cas, basculez à SQL Server Management Studio.
 Cliquez droit sur le nom du serveur  Propriétés  Security :

 Choisissez : SQL Server and Windows Authentication.

 Redémarrez le Serveur : Cliquez droit sur le nom du serveur  Restart


(Redémarrez).

 Exécuter le programme : Erreur au niveau de la ligne suivante :

dr = CmdSelect.ExecuteReader();

L’utilisateur Ali_U n’a pas le droit d’exécuter Select sur la table Client.

3 – Côté SQL Server :

Donnons maintenant ce droit à l’utilisateur Ali_U :

GRANT SELECT ON Client TO Ali_U

4 – Côté C# (Visual Studio) :

 Exécuter le programme : le formulaire s’affiche et la navigation et la recherche


marchent sans problème.

 Essayez maintenant l’ajout d’un client : Erreur au niveau de la ligne suivante :

12 / 90
CmdInsert.ExecuteNonQuery();

L’utilisateur Ali n’a pas le droit d’exécuter INSERT sur la table Client.

5 – Côté SQL Server :

Donnons maintenant ce droit à l’utilisateur Ali_U :

GRANT INSERT ON Client TO Ali_U

6 – Côté C# (Visual Studio) :

 Exécuter le programme : le formulaire s’affiche et l’ajout marche sans problème.

 Essayez maintenant la modification d’un client : Erreur au niveau de la ligne


suivante :

CmdUpdate.ExecuteNonQuery();

L’utilisateur Ali_U n’a pas le droit d’exécuter UPDATE sur la table Client.

7 – Côté SQL Server :

Donnons maintenant ce droit à l’utilisateur Ali_U :

GRANT UPDATE ON Client TO Ali_U

8 – Côté C# (Visual Studio) :

 Exécuter le programme : le formulaire s’affiche et la modification marche sans


problème.

 Essayez maintenant la suppression d’un client : Erreur au niveau de la ligne


suivante :

CmdDelete.ExecuteNonQuery();

L’utilisateur Ali_U n’a pas le droit d’exécuter DELETE sur la table Client.

9 – Côté SQL Server :

Donnons maintenant ce droit à l’utilisateur Ali_U :

GRANT DELETE ON Client TO Ali_U

10 – Côté C# (Visual Studio) :

 Exécuter le programme : le formulaire s’affiche et la suppression marche sans


problème.
13 / 90
Crystal Report

I - Conditions préalables :

Commencez par Installer : CRforVS_13_0_18.exe (Crystal Report pour VS 2013).


C’est un fichier que vous pouvez télécharger sur Internet.

(CRforVS_13_0_19.exe  Crystal Report pour VS 2015


CRforVS_13_0_21.exe  Crystal Report pour VS 2015 & VS 2017).

Ensuite, ajouter dans app.config l’attribut useLegacyV2RuntimeActivationPolicy


(dans la balise <startup> de la façon suivante :

<startup useLegacyV2RuntimeActivationPolicy="true">

Puis, enregistrez.

App.config :

14 / 90
II – Démarche pour la création d’un rapport Crystal :

1 – Créer le rapport crystal : (à l’aide de l’assistant)


Vous obtenez un fichier : Nom_Crystal.rpt

2 – Ajouter un formulaire pour visualiser le rapport :


 Faites glisser dans le formulaire un CrystalReportViewer à partir de la
boite à outils (Groupe Reporting).
 Le CrystalReportViewer occupe tout le formulaire.
 Dans la balise active du CrystalReportViewer, selectionner Choisir un
rapport crystal. (Tous vos rapports sont visibles).
 Au choix d’un rapport une instance de ce dernier est créée en bas du
formulaire. (soit Nom_Crystal1)
 Double cliquer sur la barre de titre. Taper le code suivant dans
Form_Load :
Nom_Crystal1.SetDataSource(dc.Table ou dc.Vue) ;
 Exécuter le formulaire.

III – Création d’un rapport crystal :

 Ciquer droit sur le nom du projet. Ajouter  Nouvel élément.

15 / 90
 Taper un nom et Ciquer sur Ajouter.

16 / 90
Déploiement d’une application :

Conditions préalables :

Commencez par Installer : InstallShield2015LimitedEdition.exe (pour VS 2013).


C’est un fichier que vous pouvez télécharger sur Internet.

Vous devez ensuite l’activer à l’aide d’une clé d’activation qui vous sera fourni dans une
page juste après le lancement du téléchargement.

17 / 90
Fin du Cours

Navigating Relationships

LINQ to SQL manages joins and correlated sub queries when associations are defined :

var topMovies =
ctx.Movies
.Where(m => m.Reviews.Count > 3)
.OrderByDescending(m => m.Reviews.Average(r => r.Rating))
.Take(10);

foreach (Movie m in topMovies)


{
Console.WriteLine(m.Title);
foreach (Review r in m.Reviews)
{
18 / 90
Console.WriteLine("\t{0}:{1}", r.Reviewer, r.Rating);
}
}

Projections with LINQ to SQL

 Project a named or anonymous type


 Note: you are not loading a proper entity (no updates or deletes)
 Useful for reporting, mapping into DTOs

var movieSummaries =
from movie in ctx.Movies
orderby movie.Reviews.Average(r => r.Rating)
select new
{
Title = movie.Title,
ReviewCount = movie.Reviews.Count,
AverageRating = movie.Reviews.Average(r => (float)r.Rating)
};

foreach (var summary in movieSummaries)


{
Console.WriteLine("{0,-40}\n\t {1,2}:{2}",
summary.Title, summary.ReviewCount, summary.AverageRating);
}

Compiled Queries

 There is some overheard in the SQL translation


- How much overhead depends on the types of queries you need
 CompiledQuerycan cache a translated LINQ query

var findMovieByIDQuery =
CompiledQuery.Compile(
(MovieReviewDataContext dc, int movieID) =>
(from movie in dc.Movies
where movie.ID == movieID
select movie).FirstOrDefault()
);

using (MovieReviewDataContext ctx = new


MovieReviewDataContext(connectionString))
{
Movie movie = findMovieByIDQuery(ctx, 1);
}

19 / 90
Executing SQL

 You may need to execute an arbitrary SQL command


- Use ExecuteQueryto process a resultset
Column names mapped to properties
- Use ExecuteCommandto retrieve a scalar value

var moreMovies =
ctx.ExecuteQuery<Movie>(
"SELECT * FROM movies WHERE movie_id< {0}", 10);

foreach (var movie in moreMovies)


{
Console.WriteLine(movie.Title);
}

Query Examples

https://msdn.microsoft.com/en-us/library/bb386962(v=vs.110).aspx

var averageUnitPrice = (from prod in db.Products


select prod.UnitPrice).Average();

System.Int32 notDiscontinuedCount =
(from prod in db.Products
where !prod.Discontinued
select prod)
.Count();

20 / 90
System.Nullable<Int16> maxUnitsInStock =
(from prod in db.Products
select prod.UnitsInStock)
.Max();

var maxQuery =
from prod in db.Products
group prod by prod.CategoryID into grouping
select new
{
grouping.Key,
MostExpensiveProducts =
from prod2 in grouping
where prod2.UnitPrice == grouping.Max(prod3 =>
prod3.UnitPrice)
select prod2
};

foreach (var grp in maxQuery)


{
Console.WriteLine(grp.Key);
foreach (var listing in grp.MostExpensiveProducts)
{
Console.WriteLine(listing.ProductName);
}
}

System.Nullable<Decimal> lowestUnitPrice =
(from prod in db.Products
select prod.UnitPrice)
.Min();

System.Nullable<Decimal> totalFreight =
(from ord in db.Orders
select ord.Freight)
.Sum();

http://linqsamples.com/linq-to-objects/aggregation/Average

21 / 90
Aggregate Simple
private static void Sample_Aggregate_Lambda_Simple()
{
var numbers = new int[] { 1, 2, 3, 4, 5 };

var result = numbers.Aggregate((a, b) => a * b);

Debug.WriteLine("Aggregated numbers by multiplication:");


Debug.WriteLine(result);
}
Output:
Aggregated numbers by multiplication:
120

Aggregate Seed

private static void Sample_Aggregate_Lambda_Seed()


{
var numbers = new int[] { 1, 2, 3 };

var result = numbers.Aggregate(10, (a, b) => a + b);

Debug.WriteLine("Aggregated numbers by addition with a seed of 10:");


Debug.WriteLine(result);
}
Output:
Aggregated numbers by addition with a seed of 10:
16

Count
static void Sample_Count_Lambda()
{
string[] names = { "Peter", "John", "Kathlyn", "Allen", "Tim" };

var result = names.Count();

Debug.WriteLine("Counting names gives:");


Debug.WriteLine(result);
}
Output:
Counting names gives:
5

Max

static void Sample_Max_Lambda()


{
int[] numbers = { 2, 8, 5, 6, 1 };

22 / 90
var result = numbers.Max();

Debug.WriteLine("Highest number is:");


Debug.WriteLine(result);
}
Output:
Highest number is:
8

Min

static void Sample_Min_Lambda()


{
int[] numbers = { 6, 9, 3, 7, 5 };

var result = numbers.Min();

Debug.WriteLine("Lowest number is:");


Debug.WriteLine(result);
}
Output:
Lowest number is:
3

Sum

static void Sample_Sum_Lambda()


{
int[] numbers = { 2, 5, 10 };

var result = numbers.Sum();

Debug.WriteLine("Summing the numbers yields:");


Debug.WriteLine(result);
}
Output:
Summing the numbers yields:
17

Average

static void Sample_Average_Lambda()


{
int[] numbers = { 10, 10, 11, 11 };

var result = numbers.Average();

Debug.WriteLine("Average is:");

23 / 90
Debug.WriteLine(result);
}
Output:
Average is:
10.5

ElementAt

static void Sample_ElementAt_Lambda()


{
string[] words = { "One", "Two", "Three" };

var result = words.ElementAt(1);

Debug.WriteLine("Element at index 1 in the array is:");


Debug.WriteLine(result);
}
Output:
Element at index 1 in the array is:
Two

ElementAtOrDefault

static void Sample_ElementAtOrDefault_Lambda()


{
string[] colors = { "Red", "Green", "Blue" };

var resultIndex1 = colors.ElementAtOrDefault(1);

var resultIndex10 = colors.ElementAtOrDefault(10);

Debug.WriteLine("Element at index 1 in the array contains:");


Debug.WriteLine(resultIndex1);

Debug.WriteLine("Element at index 10 in the array does not exist:");


Debug.WriteLine(resultIndex10 == null);
}
Output:
Element at index 1 in the array contains:
Green
Element at index 10 in the array does not exist:
True

First Simple

// Note: Operator First will throw an exception, if there is not at least one element
in the sequence.

24 / 90
static void Sample_First_Lambda_Simple()
{
string[] fruits = { "Banana", "Apple", "Orange" };

var result = fruits.First();

Debug.WriteLine("First element in the array is:");


Debug.WriteLine(result);
}
Output:
First element in the array is:
Banana

First Conditional

static void Sample_First_Lambda_Conditional()


{
string[] countries = { "Denmark", "Sweden", "Norway" };

var result = countries.First(c => c.Length == 6);

Debug.WriteLine("First element with a length of 6 characters:");


Debug.WriteLine(result);
}
Output:
First element with a length of 6 characters:
Sweden

FirstOrDefault

// Note: While First() will throw an exception if array...


// ...is empty, FirstOrDefault gracefully returns null.
static void Sample_FirstOrDefault_Lambda()
{
string[] countries = { "Denmark", "Sweden", "Norway" };
string[] empty = { };

var result = countries.FirstOrDefault();

var resultEmpty = empty.FirstOrDefault();

Debug.WriteLine("First element in the countries array contains:");


Debug.WriteLine(result);

Debug.WriteLine("First element in the empty array does not exist:");


Debug.WriteLine(resultEmpty == null);
}
Output:
First element in the countries array contains:
Denmark
First element in the empty array does not exist:

25 / 90
True

Last

static void Sample_Last_Lambda()


{
int[] numbers = { 7, 3, 5 };

var result = numbers.Last();

Debug.WriteLine("Last number in array is:");


Debug.WriteLine(result);
}
Output:
Last number in array is:
5

Single

// Note: Single will throw an Exception, if there is not exactly one element in the
array.
static void Sample_Single_Lambda()
{
string[] names1 = { "Peter" };
string[] names3 = { "Peter", "Joe", "Wilma" };
string[] empty = { };

var result1 = names1.Single();

Debug.WriteLine("The only name in the array is:");


Debug.WriteLine(result1);

try
{
// This will throw an exception because array contains no elements
var resultEmpty = empty.Single();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}

try
{
// This will throw an exception as well because array contains more than one
element
var result3 = names3.Single();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
Output:

26 / 90
The only name in the array is:
Peter
A first chance exception of type 'System.InvalidOperationException' occurred in
System.Core.dll
Sequence contains no elements
A first chance exception of type 'System.InvalidOperationException' occurred in
System.Core.dll
Sequence contains more than one element

GroupBy

static void Sample_GroupBy_Lambda()


{
int[] numbers = { 10, 15, 20, 25, 30, 35 };

var result = numbers.GroupBy(n => (n % 10 == 0));

Debug.WriteLine("GroupBy has created two groups:");


foreach (IGrouping<bool, int> group in result)
{
if (group.Key == true)
Debug.WriteLine("Divisible by 10");
else
Debug.WriteLine("Not Divisible by 10");

foreach (int number in group)


Debug.WriteLine(number);
}
}
Output:
GroupBy has created two groups:
Divisible by 10
10
20
30
Not Divisible by 10
15
25
35

Join

static void Sample_Join_Lambda()


{
string[] warmCountries = { "Turkey", "Italy", "Spain", "Saudi Arabia", "Etiobia" };

27 / 90
string[] europeanCountries = { "Denmark", "Germany", "Italy", "Portugal", "Spain"
};

var result = warmCountries.Join(europeanCountries, warm => warm, european =>


european, (warm, european) => warm);

Debug.WriteLine("Joined countries which are both warm and Europan:");


foreach (var country in result) // Note: result is an anomymous type, thus must use
a var to iterate.
Debug.WriteLine(country);
}
Output:
Joined countries which are both warm and Europan:
Italy
Spain

GroupJoin

class Language
{
public int Id { get; set; }
public string Name { get; set; }
}

class Person
{
public int LanguageId { get; set; }
public string FirstName { get; set; }
}

static void Sample_GroupJoin_Lambda()


{
Language[] languages = new Language[]
{
new Language {Id = 1, Name = "English"},
new Language {Id = 2, Name = "Russian"}
};

Person[] persons = new Person[]


{
new Person { LanguageId = 1, FirstName = "Tom" },
new Person { LanguageId = 1, FirstName = "Sandy" },
new Person { LanguageId = 2, FirstName = "Vladimir" },
new Person { LanguageId = 2, FirstName = "Mikhail" },
};

var result = languages.GroupJoin(persons, lang => lang.Id, pers => pers.LanguageId,


(lang, ps) => new { Key = lang.Name, Persons = ps });

Debug.WriteLine("Group-joined list of people speaking either English or Russian:");


foreach (var language in result)
{
Debug.WriteLine(String.Format("Persons speaking {0}:", language.Key));

foreach (var person in language.Persons)


{

28 / 90
Debug.WriteLine(person.FirstName);
}
}
}
Output:
Group-joined list of people speaking either English or Russian:
Persons speaking English:
Tom
Sandy
Persons speaking Russian:
Vladimir
Mikhail

OrderBy Numbers

static void Sample_OrderBy_Lambda_Numbers()


{
int[] numbers = { 7, 9, 5 };

var result = numbers.OrderBy(n => n);

Debug.WriteLine("Ordered list of numbers:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Ordered list of numbers:
5
7
9

OrderBy

static void Sample_OrderBy_Lambda_Dates()


{
var dates = new DateTime[] {
new DateTime(2015, 2, 15),
new DateTime(2015, 3, 25),
new DateTime(2015, 1, 5)
};

var result = dates.OrderBy(d => d);

Debug.WriteLine("Ordered list of dates:");


foreach (DateTime dt in result)
Debug.WriteLine(dt.ToString("yyyy/MM/dd"));
}
Output:

29 / 90
Ordered list of dates:
2015-01-05
2015-02-15
2015-03-25

class Car
{
public string Name { get; set; }
public int HorsePower { get; set; }
}

static void Sample_OrderBy_Lambda_Objects()


{
Car[] cars =
{
new Car { Name = "Super Car", HorsePower = 215 },
new Car { Name = "Economy Car", HorsePower = 75 },
new Car { Name = "Family Car", HorsePower = 145 },
};

var result = cars.OrderBy(c => c.HorsePower);

Debug.WriteLine("Ordered list of cars by horsepower:");


foreach (Car car in result)
Debug.WriteLine(String.Format("{0}: {1} horses", car.Name, car.HorsePower));
}
Output:
Ordered list of cars by horsepower:
Economy Car: 75 horses
Family Car: 145 horses
Super Car: 215 horses

static void Sample_OrderByDescending_Lambda()


{
string[] names = { "Ned", "Ben", "Susan" };

var result = names.OrderByDescending(n => n);

Debug.WriteLine("Descending ordered list of names:");


foreach (string name in result)
Debug.WriteLine(name);
}
Output:
Descending ordered list of names:
Susan
Ned

30 / 90
Ben

static void Sample_Reverse_Lambda()


{
char[] characters = { 's', 'a', 'm', 'p', 'l', 'e' };

var result = characters.Reverse();

Debug.WriteLine("Characters in reverse order:");


foreach (char character in result)
Debug.WriteLine(character);
}
Output:
Characters in reverse order:
e
l
p
m
a
s

static void Sample_ThenBy_Lambda()


{
string[] capitals = { "Berlin", "Paris", "Madrid", "Tokyo", "London",
"Athens", "Beijing", "Seoul" };

var result = capitals.OrderBy(c => c.Length).ThenBy(c => c);

Debug.WriteLine("Ordered list of capitals, first by length and then


alphabetical:");
foreach (string capital in result)
Debug.WriteLine(capital);
}
Output:
Ordered list of capitals, first by length and then alphabetical:
Paris
Seoul
Tokyo
Athens
Berlin
London
Madrid

31 / 90
Beijing

static void Sample_ThenByDescending_Lambda()


{
var dates = new DateTime[] {
new DateTime(2015, 3, 1),
new DateTime(2014, 7, 1),
new DateTime(2013, 5, 1),
new DateTime(2015, 1, 1),
new DateTime(2015, 7, 1)
};

var result = dates.OrderByDescending(d => d.Year).ThenByDescending(d => d.Month);

Debug.WriteLine("List of dates first ordered by year descending, and then by month


descending:");
foreach (DateTime dt in result)
Debug.WriteLine(dt.ToString("yyyy/MM/dd"));
}
Output:
List of dates first ordered by year descending, and then by month descending:
2015-07-01
2015-03-01
2015-01-01
2014-07-01
2013-05-01

static void Sample_Concat_Lambda_Numbers()


{
int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 4, 5, 6 };

var result = numbers1.Concat(numbers2);

Debug.WriteLine("Concatenating numbers1 and numbers2 gives:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Concatenating numbers1 and numbers2 gives:
1
2
3
4
5

32 / 90
6

static void Sample_Concat_Lambda_Strings()


{
string[] vegetables = { "Tomato", "Cucumber", "Carrot" };
string[] fruits = { "Apples", "Grapes", "Banana" };

var result = vegetables.Concat(fruits);

Debug.WriteLine("Concatinating vegetables and fruits gives:");


foreach (string piece in result)
Debug.WriteLine(piece);
}
Output:
Concatinating vegetables and fruits gives:
Tomato
Cucumber
Carrot
Apples
Grapes
Banana

static void Sample_Skip_Lambda()


{
string[] words = { "one", "two", "three", "four", "five", "six" };

var result = words.Skip(4);

Debug.WriteLine("Skips the first 4 words:");


foreach (string word in result)
Debug.WriteLine(word);
}
Output:
Skips the first 4 words:
five
six

static void Sample_SkipWhile_Lambda()


{
string[] words = { "one", "two", "three", "four", "five", "six" };

var result = words.SkipWhile(w => w.Length == 3);

Debug.WriteLine("Skips words while the condition is met:");


foreach (string word in result)

33 / 90
Debug.WriteLine(word);
}
Output:
Skips words while the condition is met:
three
four
five
six

static void Sample_Take_Lambda()


{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var result = numbers.Take(5);

Debug.WriteLine("Takes the first 5 numbers only:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Takes the first 5 numbers only:
1
2
3
4
5

static void Sample_TakeWhile_Lambda()


{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var result = numbers.TakeWhile(n => n < 5);

Debug.WriteLine("Takes numbers one by one, and stops when condition is no longer


met:");
foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Takes numbers one by one, and stops when condition is no longer met:
1
2
3

34 / 90
4

static void Sample_Select_Lambda_Simple()


{
decimal[] numbers = { 3.4M, 8.33M, 5.225M };

var result = numbers.Select(n => Math.Floor(n));

Debug.WriteLine("Numbers rounded down:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Numbers rounded down:
3
8
5

static void Sample_Select_Lambda_Anonymous()


{
double[] angles = { 30D, 60D, 90D }; // Angles in radians

var result = angles.Select(a => new { Angle = a, Cos = Math.Cos(a), Sin =


Math.Sin(a) });

Debug.WriteLine("Calculated values:");
foreach (var res in result)
Debug.WriteLine(String.Format("Angle {0}: Cos = {1}, Sin = {2}", res.Angle,
res.Cos, res.Sin));
}
Output:
Calculated values:
Angle 30: Cos = 0,154251449887584, Sin = -0,988031624092862
Angle 60: Cos = -0,952412980415156, Sin = -0,304810621102217
Angle 90: Cos = -0,44807361612917, Sin = 0,893996663600558

static void Sample_Select_Lambda_Indexed()


{
string[] words = { "one", "two", "three" };

var result = words.Select((w, i) => new


{
Index = i,
Value = w

35 / 90
});

Debug.WriteLine("Words with index and value:");


foreach (var word in result)
Debug.WriteLine(String.Format("Index {0} is {1}", word.Index, word.Value));
}
Output:
Words with index and value:
Index 0 is one
Index 1 is two
Index 2 is three

static void Sample_SelectMany_Lambda()


{
string[] fruits = { "Grape", "Orange", "Apple" };
int[] amounts = { 1, 2, 3 };

var result = fruits.SelectMany(f => amounts, (f, a) => new


{
Fruit = f,
Amount = a
});

Debug.WriteLine("Selecting all values from each array, and mixing them:");


foreach (var o in result)
Debug.WriteLine(o.Fruit + ", " + o.Amount);
}
Output:
Selecting all values from each array, and mixing them:
Grape, 1
Grape, 2
Grape, 3
Orange, 1
Orange, 2
Orange, 3
Apple, 1
Apple, 2
Apple, 3

static void Sample_All_Lambda()


{
string[] names = { "Bob", "Ned", "Amy", "Bill" };

var result = names.All(n => n.StartsWith("B"));

Debug.WriteLine("Does all of the names start with the letter 'B':");


36 / 90
Debug.WriteLine(result);
}
Output:
Does all of the names start with the letter 'B':
False

static void Sample_Any_Lambda()


{
string[] names = { "Bob", "Ned", "Amy", "Bill" };

var result = names.Any(n => n.StartsWith("B"));

Debug.WriteLine("Does any of the names start with the letter 'B':");


Debug.WriteLine(result);
}
Output:
Does any of the names start with the letter 'B':
True

static void Sample_Contains_Lambda()


{
int[] numbers = { 1, 3, 5, 7, 9 };

var result = numbers.Contains(5);

Debug.WriteLine("sequence contains the value 5:");


Debug.WriteLine(result);
}
Output:
Sequence contains the value 5:
True

static void Sample_Where_Lambda_Numbers()


{
int[] numbers = { 5, 10, 15, 20, 25, 30 };

var result = numbers.Where(n => n >= 15 && n <= 25);

Debug.WriteLine("Numbers being >= 15 and <= 25:");


foreach (var number in result)
Debug.WriteLine(number);
}
Output:
Numbers being >= 15 and <= 25:
15

37 / 90
20
25

class Person
{
public string Name { get; set; }
public int Age { get; set; }
}

static void Sample_Where_Lambda_Objects()


{
Person[] persons = {
new Person { Name = "Mike", Age = 25 },
new Person { Name = "Joe", Age = 43 },
new Person { Name = "Nadia", Age = 31 }
};

var result = persons.Where(p => p.Age >= 30);

Debug.WriteLine("Finding persons who are 30 years old or older:");


foreach (Person person in result)
Debug.WriteLine(String.Format("{0}: {1} years old", person.Name, person.Age));
}
Output:
Finding persons who are 30 years old or older:
Joe: 43 years old
Nadia: 31 years old

static void Sample_Where_Lambda_Indexed()


{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

var result = numbers.Where((n, i) => n % 3 == 0 && i >= 5);

Debug.WriteLine("Numbers divisible by 3 and indexed >= 5:");


foreach (var number in result)
Debug.WriteLine(number);
}
Output:
Numbers divisible by 3 and indexed >= 5:
6
9

static void Sample_Distinct_Lambda()


{
int[] numbers = { 1, 2, 2, 3, 5, 6, 6, 6, 8, 9 };

38 / 90
var result = numbers.Distinct();

Debug.WriteLine("Distinct removes duplicate elements:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Distinct removes duplicate elements:
1
2
3
5
6
8
9

static void Sample_Except_Lambda()


{
int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 3, 4, 5 };

var result = numbers1.Except(numbers2);

Debug.WriteLine("Except creates a single sequence from numbers1 and removes the


duplicates found in numbers2:");
foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Except creates a single sequence from numbers1 and removes the duplicates found in
numbers2:
1
2

static void Sample_Intersect_Lambda()


{
int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 3, 4, 5 };

var result = numbers1.Intersect(numbers2);

Debug.WriteLine("Intersect creates a single sequence with only the duplicates:");


foreach (int number in result)
Debug.WriteLine(number);
}

39 / 90
Output:
Intersect creates a single sequence with only the duplicates:
3

static void Sample_Union_Lambda()


{
int[] numbers1 = { 1, 2, 3 };
int[] numbers2 = { 3, 4, 5 };

var result = numbers1.Union(numbers2);

Debug.WriteLine("Union creates a single sequence and eliminates the duplicates:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
Union creates a single sequence and eliminates the duplicates:
1
2
3
4
5

static void Sample_ToArray_Lambda()


{
int[] numbers = { 1, 2, 3, 4 };

var result = numbers.ToArray();

Debug.WriteLine("New array contains identical values:");


foreach (int number in result)
Debug.WriteLine(number);
}
Output:
New array contains identical values:
1
2
3
4

40 / 90
static void Sample_ToList_Lambda()
{
string[] names = { "Brenda", "Carl", "Finn" };

List<string> result = names.ToList();

Debug.WriteLine(String.Format("names is of type: {0}", names.GetType().Name));


Debug.WriteLine(String.Format("result is of type: {0}", result.GetType().Name));
}
Output:
names is of type: String[]
result is of type: List`1

Linq To SQL et C#
Exemples de requêtes

using System.Linq;

All the underlying base system support classes for LINQ reside in theSystem.Linq namespac
a C# source file outside of Visual C# 2010 or edit a previously existing Visual C# 2005 pro
have to add the using System.Linq statement manually.
The next step is to create some data, which is done in this example by declaring and initiali
of names:

41 / 90
string[] names = { "Alonso", "Zheng", "Smith", "Jones", "Smythe", "Small",
"Ruiz", "Hsieh", "Jorgenson", "Ilyich", "Singh", "Samba", "Fatimah" };

This is a trivial set of data, but it is good to start with an example for which the result of t
obvious. The actual LINQ query statement is the next part of the program:

var queryResults = from n in names


where n.StartsWith("S")
select n;

where n.Length > 10

where n.Contains("Q")

Console.WriteLine("Names beginning with S:");


foreach (var item in queryResults) {
Console.WriteLine(item);
}

Add the following code to the Main() method inProgram.cs:

static void Main(string[] args)


{
string[] names = { "Alonso", "Zheng", "Smith", "Jones", "Smythe",
"Small", "Ruiz", "Hsieh", "Jorgenson", "Ilyich", "Singh", "Samba", "Fatimah"
};
var queryResults = names.Where(n => n.StartsWith("S"));
Console.WriteLine("Names beginning with S:");
foreach (var item in queryResults) {
Console.WriteLine(item);
}
Console.Write("Program finished, press Enter/Return to continue:");
Console.ReadLine();
}

Ordering Query Results

static void Main(string[] args)


{
string[] names = { "Alonso", "Zheng", "Smith", "Jones", "Smythe",
"Small", "Ruiz", "Hsieh", "Jorgenson", "Ilyich", "Singh", "Samba", "Fatimah" };

42 / 90
var queryResults =
from n in names
where n.StartsWith("S")
orderby n
select n;
Console.WriteLine("Names beginning with S ordered alphabetically:");
foreach (var item in queryResults) {
Console.WriteLine(item);
}
Console.Write("Program finished, press Enter/Return to continue:");
Console.ReadLine();
}

Ordering Using Method Syntax

static void Main(string[] args)


{

string[] names = { "Alonso", "Zheng", "Smith", "Jones", "Smythe",


"Small", "Ruiz", "Hsieh", "Jorgenson", "Ilyich", "Singh", "Samba", "Fatimah" };
var queryResults = names.OrderBy(n => n).Where(n => n.StartsWith("S"));
Console.WriteLine("Names beginning with S:");
foreach (var item in queryResults) {
Console.WriteLine(item);
}
Console.Write("Program finished, press Enter/Return to continue:");
Console.ReadLine();
}

AGGREGATE OPERATORS

Often a query returns more results than you might expect. For example, if you were to
change the
condition of the large-number query program you ju st created to list the numbers
greater than 1,000,
rather than the numbers less than 1,000, there would be so many query results that the
numbers would
not stop printing!
Luckily, LINQ provides a set of aggregate operators that enable you to analyze the
results of a query
without having to loop through them all. The following table shows the most commonly
used aggregate
operators for a set of numeric results such as those from the large-number query. These
may be familiar
43 / 90
to you if you have used a database query language such as SQL.
Aggregate Operators ❘ 767

OPERATOR DESCRIPTION
Count() Count of results
Min() Minimum value in results
Max() Maximum value in results
Average() Average value of numeric results
Sum() Total of all of numeric results

There are more aggregate operators, such as Aggregate() , for executing arbitrary code
in a manner
that enables you to code your own aggregate function. However, those are for advanced
users and therefore beyond the scope of this book.
NOTE because the aggregate operators return a simple scalar type instead of a
sequence for their results, their use forces immediate execution of query results
with no deferred execution.
In the following Try It Out, you modify the large-number query and use aggregate
operators to explore
the result set from the greater-than version of the large-number query using LINQ.
TRY IT OUT Numeric Aggregate Operators
Follow these steps to create the example in Visual C# 2010:
1. For this example, you can either modify the LargeNumberQuery example you just
made or create a new console project named 23-6-NumericAggregates in the directory
C:\BegVCSharp\Chapter23 .
2. As before, when you create the project, Visual C# 2010 includes theLinq namespace
method in
Program.cs. You just need to modify the Main() method as shown in the following code
and in the
rest of this Try It Out. As with the previous example, the orderbyclause is not used in this
query.
However, the condition on thewhereclause is the opposite of the previous example (the
numbers
are greater than 1,000 (n > 1000), instead of less than 1,000).
static void Main(string[] args)
{
int[] numbers = generateLotsOfNumbers(12345678);
Console.WriteLine("Numeric Aggregates");
var queryResults =
from n in numbers
768 ❘ CHAPTER 23 INTRODUCTION TO LINQ
where n > 1000
select n
;
Console.WriteLine("Count of Numbers > 1000");
Console.WriteLine(queryResults.Count());
Console.WriteLine("Max of Numbers > 1000");
Console.WriteLine(queryResults.Max());
Console.WriteLine("Min of Numbers > 1000");
Console.WriteLine(queryResults.Min());
Console.WriteLine("Average of Numbers > 1000");
Console.WriteLine(queryResults.Average());
Console.WriteLine("Sum of Numbers > 1000");

44 / 90
Console.WriteLine(queryResults.Sum(n => (long) n));
Console.Write("Program finished, press Enter/Return to continue:");
Console.ReadLine();
}

QUERYING COMPLEX OBJECTS

Before the start of theProgramclass inProgram.cs, add the following short class definition for
the
Customer class:

class Customer
{
public string ID { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Region { get; set; }
public decimal Sales { get; set; }

public override string ToString()


{
return "ID: " + ID + " City: " + City + " Country: " + Country +
" Region: " + Region + " Sales: " + Sales;
}
}

Add the following code to the Main() method of theProgramclass ofProgram.cs:


static void Main(string[] args)
{
List <Customer> customers = new List<Customer> {
new Customer { ID="A", City="New York", Country="USA",
Region="North America", Sales=9999 },
new Customer { ID="B", City="Mumbai", Country="India",
Region="Asia", Sales=8888 },
new Customer { ID="C", City="Karachi", Country="Pakistan",
Region="Asia", Sales=7777 },
new Customer { ID="D", City="Delhi", Country="India",
Region="Asia", Sales=6666 },
new Customer { ID="E", City="Sao Paulo", Country="Brazil",
45 / 90
Region="South America", Sales=5555 },
new Customer { ID="F", City="Moscow", Country="Russia",
Region="Europe", Sales=4444 },
new Customer { ID="G", City="Seoul", Country="Korea", Region="Asia",
Sales=3333 },
new Customer { ID="H", City="Istanbul", Country="Turkey",
Region="Asia", Sales=2222 },
new Customer { ID="I", City="Shanghai", Country="China", Region="Asia",
Sales=1111 },
new Customer { ID="J", City="Lagos", Country="Nigeria",
Region="Africa", Sales=1000 },
new Customer { ID="K", City="Mexico City", Country="Mexico",

Region="North America", Sales=2000 },


new Customer { ID="L", City="Jakarta", Country="Indonesia",
Region="Asia", Sales=3000 },
new Customer { ID="M", City="Tokyo", Country="Japan",
Region="Asia", Sales=4000 },
new Customer { ID="N", City="Los Angeles", Country="USA",
Region="North America", Sales=5000 },
new Customer { ID="O", City="Cairo", Country="Egypt",
Region="Africa", Sales=6000 },
new Customer { ID="P", City="Tehran", Country="Iran",
Region="Asia", Sales=7000 },
new Customer { ID="Q", City="London", Country="UK",
Region="Europe", Sales=8000 },
new Customer { ID="R", City="Beijing", Country="China",
Region="Asia", Sales=9000 },
new Customer { ID="S", City="Bogot´a", Country="Colombia",
Region="South America", Sales=1001 },
new Customer { ID="T", City="Lima", Country="Peru",
Region="South America", Sales=2002 }
};
var queryResults =
from c in customers
where c.Region == "Asia"
select c
;
Console.WriteLine("Customers in Asia:");
foreach (Customer c in queryResults)
{
Console.WriteLine(c);
}
Console.Write("Program finished, press Enter/Return to continue:");
Console.ReadLine();
}
}

46 / 90
I - Gestion de la table Client par des procédures stockées et
Linq To SQL

47 / 90
Dans la BD Vente, créer les PS suivantes :

1. Insertion client
CREATE PROCEDURE PS_InsertCl

@codecl varchar(6),
@nom varchar(40),
@ville varchar(30)

AS
Insert Into client Values(@codecl,@nom,@ville)

2. Modification client
CREATE PROCEDURE PS_UpdateCl

@codecl varchar(6),
@nom varchar(40),
@ville varchar(30)

AS
Update Client Set Nom=@nom,Ville=@ville Where Codecl=@codecl

3. Suppression client
CREATE PROCEDURE PS_DeleteCl

@codecl varchar(6)

AS
Delete client Where Codecl = @codecl

4. Recherche d'un client


CREATE PROCEDURE PS_SelectCl

@codecl varchar(6),
@nom varchar(40) output,
@ville varchar(30) output

AS
Select @nom=Nom,@ville=Ville From client Where Codecl=@codecl

Faire glisser ces 4 PS dans la partie droite du DataContext :

48 / 90
II - Gestion de la table Client avec des procédures stockées en

49 / 90
mode connecté :

using System.Data.SqlClient;

namespace GestionCommercial_Connecté_CSharp
{
public partial class MajClient_AvecPS : Form
{
public string strcon = @"Data Source=.\sqlexpress;Initial
Catalog=Vente;Integrated Security=True";

public SqlConnection con = new SqlConnection();

public SqlCommand CmdSelect = new SqlCommand();

public SqlCommand CmdMaj = new SqlCommand();

public Boolean Ajouter = false;

public MajClient_AvecPS()
{
InitializeComponent();
}

private void MajClient_AvecPS_Load( . . . )


{
con.ConnectionString = strcon;
50 / 90
CmdMaj.Connection = con;
CmdMaj.CommandType = CommandType.StoredProcedure;
CmdSelect.Connection = con;
CmdSelect.CommandType = CommandType.StoredProcedure;
CmdSelect.CommandText = "PS_SelectCl";
}

private void CmdAjouter_Click( . . . )


{
if (Ajouter == false)
{
Ajouter = true;
CmdAjouter.Text = "Ajouter";
TxtCodeCl.Clear();
TxtNom.Clear();
TxtVille.Clear();
TxtCodeCl.Focus();
}

else
{
con.Open();
CmdMaj.CommandText = "PS_InsertCl";
SqlParameter paramCodeCl = new
SqlParameter("@CodeCl", SqlDbType.VarChar,6);
paramCodeCl.Direction = ParameterDirection.Input;
paramCodeCl.Value = TxtCodeCl.Text;

SqlParameter paramNom = new


SqlParameter("@Nom",SqlDbType.VarChar,40);
paramNom.Direction = ParameterDirection.Input;
paramNom.Value = TxtNom.Text;

SqlParameter paramVille = new


SqlParameter("@Ville",SqlDbType.VarChar,30);
paramVille.Direction = ParameterDirection.Input;
paramVille.Value = TxtVille.Text;

CmdMaj.Parameters.Add(paramCodeCl);
CmdMaj.Parameters.Add(paramNom);
CmdMaj.Parameters.Add(paramVille);
CmdMaj.ExecuteNonQuery();

CmdMaj.Parameters.Clear();
con.Close();

CmdAjouter.Text = "Nouveau";
Ajouter = false;

}
}

private void CmdRechercher_Click(object sender, EventArgs e)


{

51 / 90
con.Open();

SqlParameter paramCodeCl = new


SqlParameter("@CodeCl",SqlDbType.VarChar,6);
paramCodeCl.Direction = ParameterDirection.Input;
paramCodeCl.Value = TxtRechercheCl.Text;

SqlParameter paramNom = new


SqlParameter("@Nom",SqlDbType.VarChar,40);
paramNom.Direction = ParameterDirection.Output;

SqlParameter paramVille = new


SqlParameter("@Ville",SqlDbType.VarChar,30);
paramVille.Direction = ParameterDirection.Output;

CmdSelect.Parameters.Add(paramCodeCl);
CmdSelect.Parameters.Add(paramNom);
CmdSelect.Parameters.Add(paramVille);
SqlDataReader dr = CmdSelect.ExecuteReader();

TxtCodeCl.Text = TxtRechercheCl.Text;
TxtNom.Text = CmdSelect.Parameters["@Nom"].Value.ToString();
TxtVille.Text = CmdSelect.Parameters["@Ville"].Value.ToString();

CmdSelect.Parameters.Clear();
con.Close();

private void CmdQuitter_Click( . . . )


{
this.Close();
}

private void CmdModifier_Click( . . . )


{

con.Open();
CmdMaj.CommandText = "PS_UpdateCl";

SqlParameter paramCodeCl = new


SqlParameter("@CodeCl",SqlDbType.VarChar, 6);
paramCodeCl.Direction = ParameterDirection.Input;
paramCodeCl.Value = TxtCodeCl.Text;

SqlParameter paramNom = new


SqlParameter("@Nom",SqlDbType.VarChar, 40);
paramNom.Direction = ParameterDirection.Input;
paramNom.Value = TxtNom.Text;

SqlParameter paramVille = new


SqlParameter("@Ville",SqlDbType.VarChar, 30);

52 / 90
paramVille.Direction = ParameterDirection.Input;
paramVille.Value = TxtVille.Text;

CmdMaj.Parameters.Add(paramCodeCl);
CmdMaj.Parameters.Add(paramNom);
CmdMaj.Parameters.Add(paramVille);
CmdMaj.ExecuteNonQuery();

CmdMaj.Parameters.Clear();
con.Close();

private void CmdSupprimer_Click( . . . )


{
con.Open();
CmdMaj.CommandText = "PS_DeleteCl";
SqlParameter paramCodeCl = new
SqlParameter("@CodeCl",SqlDbType.VarChar, 6);
paramCodeCl.Direction = ParameterDirection.Input;
paramCodeCl.Value = TxtCodeCl.Text;

CmdMaj.Parameters.Add(paramCodeCl);
CmdMaj.ExecuteNonQuery();

CmdMaj.Parameters.Clear();
con.Close();
}
}
}

Transaction in LINQ to SQL


What are the differences between the classic transaction pattern in LINQ to SQL like:

using(var context = Domain.Instance.GetContext())


{
try
{
context.Connection.Open();
context.Transaction = context.Connection.BeginTransaction();
/*code*/
context.Transaction.Commit();
}
catch
{
context.Transaction.Rollback();
}

53 / 90
}

*************************************************

Re: Transaction Rollback in LINQ to SQL


Sep 21, 2013 01:00 PM|LINK
i have following thing to solve the issue... i havent used TransactionScope...

//dbAdmin is my DataContext
System.Data.Common.DbTransaction trans = null;
dbAdmin.Connection.Open();
trans = dbAdmin.Connection.BeginTransaction();
dbAdmin.Transaction = trans;

try
{
//All delete queries
//All Save queries
trans.Commit();
}
catch(Exception)
{
// Rollback transaction
if (trans != null)
trans.Rollback();
return "Some error occured while saving record. Transaction has being rollbacked.";
}

***************************************************

Maintain Transaction in LINQ to SQL


Today I will tell you how to maintain transaction in LINQ to SQL.

Before going on to discuss the detail of maintaining Transaction, it should be made clear that
LINQ to SQL implicitly maintain transaction

So if there is single call to SubmitChanges() after any number of calls


to InsertOnSubmit,DeleteOnSubmit.

But if you have multiple call to SubmitChanges(), LINQ will not maintain Transaction and one has
to explicitly
maintain Transaction. And that is what we are going to discuss today.

54 / 90
In the example I am going to use, I have taken two Table2 and TestTable.

First Create object of Type System.Data.Common.DbTransaction

System.Data.Common.DbTransaction transaction;

Now Open the connection. Make sure to use the same DataContext to open connection which you
are going to use
In your LINQ operation.

DataClasses1DataContext dataContext = new DataClasses1DataContext();


dataContext.Connection.Open();

Now begin the transaction and assign it to transaction object created in first step.

transaction = dataContext.Connection.BeginTransaction();

Go on and set the dataContext Transaction property to transaction.

dataContext.Transaction = transaction;

At this point 50% of job is done.

In the try block add the logic to insert the data into the and just after SubmitChanges() add

transaction.Commit();

If transaction.Commit() line is missing database operation performed will not be reflected in


database

In the Catch block add the code

transaction.Rollback();

and final step

Don’t forget to close the connection you opened at the top

Find below the complete code


55 / 90
static void Main(string[] args)
{
DataClasses1DataContext dataContext = new DataClasses1DataContext();
System.Data.Common.DbTransaction transaction;
dataContext.Connection.Open();
transaction = dataContext.Connection.BeginTransaction();
dataContext.Transaction = transaction;

try
{
Table2 tbl2 = new Table2()
{
ID = 1,
Value = "Test Data"
};

dataContext.Table2s.InsertOnSubmit(tbl2);

TestTable tstTbl = new TestTable()


{
ID = 1,
Name = "Alpha",
lastname = "Beta"
};

dataContext.TestTables.InsertOnSubmit(tstTbl);

dataContext.SubmitChanges();

transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
Console.WriteLine("Rolback Done");
}
finally
{
if (null != dataContext.Connection)
{
dataContext.Connection.Close();
}
}
}

This is all that needs to be done to maintain Transaction in LINQ.

*******************************************************

How to use transaction in LINQ using C#


August 25, 2007 by chiragrdarji

56 / 90
I installed VS 2008 beta 2 before few days and started exploring it. I looked in to the LINQ and found

very interesting. LINQ generates DataContext class which provides classes and methods which is used in OR-

Mapping. You can also use your stored procedures and views with LINQ. You may require to use transaction

with your SPs during Insert, Delete or Update operations.

System.Data.Common.DbTransaction class provides the Transaction object. I have

used Northwind database in this example. Lets start with new project, you can select new project from Start

-> All Programs -> Microsoft Visual Studio 2008 Beta 2 and click on Microsoft Visual Studio 2008 Beta 2.

Create new Asp.netwebsite. Right click on website from solution explorer and select LINQ to SQL classes from

Add New Item as shown below.

Fig – (1) LINQ to SQL classes

This will generate dbml file in App_Code folder. Select the tables, views, stored procedures and

function from server explorer and drag it on dbml file. DataContext class generates methods for each SPs,

functions and views.

I have used Category and Product tables in this example. I have created two SPs InsertCategory and

InsertProduct for inserting records in appropriate tables. You can see your SPs when you create the object of

DataContext class.

Fig – (2) DataContext class shows the methods generated for SPs

57 / 90
I will first insert the category and then insert product for newly created category. If you have

used some parameters as OUT parameters in your SP, you need to pass these parameters as Ref in calling

method. In my SPs I have used CategoryID and ProductID as OUT parameters.

Now, lets move towards the transaction. I want that either category and product both will be added in

database or none of them will be inserted. Below is the code for that,

System.Data.Common.DbTransaction trans = null;

DataClassesDataContext objDataClass = new DataClassesDataContext

(ConfigurationManager.ConnectionStrings

[Constants.ConnectionString].ConnectionString);

try

// Nullable data type as the methods generated for SP will use Nullable

// type

int? intCategoryID =0;

int? intProductID =0;

// Open the connection

objDataClass.Connection.Open();

// Begin the transaction

trans = objDataClass.Connection.BeginTransaction();

// Assign transaction to context class

// All the database operation perform by this object will now use

//transaction

objDataClass.Transaction = trans;

// Insert Category

// I have to use Ref keyword CategoryID of newly added category will

// be assign to this variable

objDataClass.InsertCategory

ref intCategoryID,

txtName.Text.Trim().Replace(“‘”, “””),

txtDescription.Text.Trim().Replace(“‘”, “””),

new byte[0]

);

// Insert Product

// I have to use Ref keyword as ProductID of newly generated product will

58 / 90
// be assign to this variable

objDataClass.InsertProduct

ref intProductID,

txtProductName.Text.Trim().Replace(“‘”,“””),

null,

intCategoryID,

txtQuantityPerUnit.Text.Trim().Replace(“‘”, “””),

Convert.ToDecimal(

txtUnitPrice.Text.Trim().Replace(“‘”, “””)

),

null,

null,

null,

0);

// Commit transaction

trans.Commit();

catch (Exception ex)

// Rollback transaction

if (trans != null)

trans.Rollback();

finally

// Close the connection

if (objDataClass.Connection.State == ConnectionState.Open)

objDataClass.Connection.Close();

Fig – (3) Code for Transaction in LINQ using C#

Happy Programming !!

********************************************

59 / 90
Transactions with LINQ to SQL
This post shows how to implement Transaction with LINQ to SQL

LINQ to SQL supports three distinct transaction models. The following lists describes them all.

1) Explicit Local Transaction

When SubmitChanges is called, if the Transaction property is set to a


(IDbTransaction) transaction, the SubmitChanges call is executed in the context of
the same transaction.

It is your responsibility to commit or rollback the transaction after successful


execution of the transaction. The connection corresponding to the transaction must
match the connection used for constructing the DataContext. An exception is
thrown if a different connection is used.

2) Explicit Distributable Transaction

You can call LINQ to SQL APIs (including but not limited to SubmitChanges) in the scope of an
active Transaction. LINQ to SQL detects that the call is in the scope of a transaction and does
not create a new transaction. LINQ to SQL also avoids closing the connection in this case. You
can perform query and SubmitChanges executions in the context of such a transaction.

3) Implicit Transaction

When you call SubmitChanges, LINQ to SQL checks to see whether the call is in the
scope of a Transaction or if theTransaction property (IDbTransaction) is set to a
user-started local transaction. If it finds neither transaction, LINQ to SQL starts a
local transaction (IDbTransaction) and uses it to execute the generated SQL
commands. When all SQL commands have been successfully completed, LINQ to
SQL commits the local transaction and returns.

->Example of simple transaction:-

This is a vary simple example for implementing transaction which implements one
insert and one update statement within one transaction. If any Error comes the last
statement of Try block will not be executed and data of any statement will not be
reflected to database.

try

{
//OBJECT OF YOUR DATA CONTEXT CLASSS (.DBML FILE)

LINQ_to_SQL_ClassDataContext DataContexClassObject = new


LINQ_to_SQL_ClassDataContext();

60 / 90
//OBJECT OF TABLE IN DATABASE (DRAGED IN DATA CONTEXT CLASS)

Product_Master Prod = new Product_Master();

//ASSIGN VALUE TO FIELDS OF YOUR TABLE

Prod.Field1 = 1001;
Prod.Field2 = "My new Product";
Prod.Field3 = "This is new product";
Prod.Field4 = 10.00;
Prod.Field5 = 500;

//INSERT DATA TO YOUR DATA CONTEXT CLASS TABLE

DataContexClassObject.Product_Master.InsertOnSubmit(Prod);
DataContexClassObject.SubmitChanges();

//ANOTHER OBJECT OF TABLE IN DATABASE (DRAGED IN DATA CONTEXT CLASS)

Order_Book OrderUpdate = new Order_Book();


OrderUpdate = //LINQ Query which whil return one record which you want to
update

//ASSIGN VALUE TO FIELDS OF YOUR TABLE

OrderUpdate.Field3 = "New data for updating previous";


OrderUpdate.Field5 = 550;

//UPDATE DATA TO YOUR DATA CONTEXT CLASS TABLE

DataContexClassObject.Order_Book.InsertOnSubmit(OrderUpdate);
DataContexClassObject.SubmitChanges();

//FINALLY TO UPDATE ENTRIES TO DATABASE TABLES

dcCSE.SubmitChanges();

//TRANSACTION EXECUTED SUCCESSFULLY


}

catch (Exception ex)


{
//TRANSACTION NOT EXECUTED NO EFFECT HAS BEEN MADE TO DATABASE
}

61 / 90
Manipulation d’un document XML avec C#

Pour travailler avec un document XML dans une application C#.NET on doit utiliser le
DOM (Document Object Model). Le DOM vous permet de lire, de manipuler et de modifier
un document XML par programme. Ce dernier gère la représentation en mémoire des donnés

62 / 90
bien que les données XML véritables soient stockées de façon linéaire lorsqu’elles se
trouvent dans un fichier ou qu’elles proviennent d’un autre objet.
Par exemple, le document suivant :
<?xml version="1.0"?>
<restaurant>
<menu prix="10">
<entree>radis</entree>
<plat>cassoulet</plat>
<dessert>glace</dessert>
</menu>
<boisson>
<jus>orange</jus>
<limonade>muscadet</limonade>
</boisson>
</restaurant>

est représenté sous cette forme en mémoire dans une application :

Dans la structure d’un document XML, chaque cercle de cette illustration représente un
nœud, appelé objet XmlNode qui est l’objet de base de l’arborescence DOM. La classe
XmlDocument prend en charge des méthodes destinées à exécuter des opérations sur le
document dans son ensemble, par exemple pour le charger en mémoire ou l’enregistrer sous
la forme d’un fichier. Les objets XmlNode comportent un ensemble de méthodes et de
propriétés, ainsi que des caractéristiques de base bien définies.

Voici certaines de ces caractéristiques :

 Un nœud ne possède qu’un seul nœud parent (parentNode), qui est le nœud situé
juste audessus de lui.

 Le seul nœud qui est dépourvu de parent est la racine du document, puisqu’il s’agit du
nœud de premier niveau qui contient le document luimême et les fragments de docu-
ment.
63 / 90
 La plupart des nœuds peuvent comporter plusieurs nœuds enfants (ChildNodes), qui
sont les nœuds situés directement sous eux.

 Les nœuds situés au même niveau, représentés dans le diagramme par les nœuds
menu et boisson, sont des nœuds frères (Sibling).

L’une des caractéristiques du DOM est la manière dont il gère les attributs. Les attributs ne
sont pas des nœuds qui font partie des relations parentenfant et frère. Ils sont considérés
comme une propriété du nœud et sont constitués d’une paire, composée d’un nom et d’une
valeur.

Dans notre exemple, prix = "10" associé à l’élément menu, le mot prix correspond au nom
et la valeur de l’attribut prix est 10. Pour extraire l’attribut prix = "10" du nœud menu, vous
appelez la méthode GetAttribute lorsque le curseur se trouve sur le nœud menu.

Pour les exemples qui suivent, nous utiliserons le document XML suivant (resto.xml) :

<?xml version="1.0" encoding="utf-8" ?>


<restaurant>
<menu type="gastronomique">
<entrees>
<nom calories="50">radis</nom>
<nom calories="300">pate</nom>
<nom calories="350">saucisson</nom>
</entrees>
<plats>
<nom calories="1000">choucroute</nom>
<nom calories="2000">cassoulet</nom>
<nom calories="1700">couscous</nom>
</plats>
<fromages>
<nom calorie="240">camembert</nom>
<nom calories="300">brie</nom>
<nom calories="120">roquefort</nom>
</fromages>
<desserts>
<nom calories="340" parfum="chocolat">glace</nom>
<nom calories="250" fruits="pommes">tarte</nom>
<nom calories="400">creme brule</nom>
</desserts>
</menu>

<menu type="economique">
<entrees>
<nom calories="50">pain</nom>
</entrees>
<plats>
<nom calories="1700">jambon</nom>
</plats>
<fromages>

64 / 90
<nom calorie="240">camembert</nom>
</fromages>
<desserts>
<nom calories="340" parfum="a l’eau">glace</nom>
</desserts>
</menu>
</restaurant>

I - Utilisation de DOM

La première étape, lors de l’utilisation de DOM, consiste à charger le document XML


dans un arbre de nœuds DOM. Vous devez pour cela déclarer un objet XmlDocument puis
utiliser la méthode Load pour remplir cet objet à partir d’un fichier XML.

public XmlDocument document = new XmlDocument();


document.Load("resto.xml");

Il est également possible de charger des données XML à partir d’une chaîne de
caractères. Vous devez, dans ce cas, utiliser la méthode LoadXML en lui fournissant la chaîne
de caractères contenant les données XML.

Une fois les données XML chargées dans l’arbre, vous pouvez localiser des nœuds
particuliers afin de les soumettre à des opérations de traitement, de manipulation ou de
modification. La méthode GetElementsByTagName permet d’obtenir un objet XmlNodeList
contenant les nœuds concernés. Vous pouvez alors obtenir les attributs du nœud en utilisant
la propriété Attributes ou vérifier s’ils possèdent des nœuds enfants avec la propriété
HasChildNodes. Si c’est le cas, vous avez accès à ces nœuds à l’aide de la propriété
ChildNodes sous forme d’un objet XmlNodeList.

 Exemple 1 : L’exemple suivant recherche les nœuds «menu» dans


l’arborescence et affiche l’attribut type.


Code C# :

using System.Xml;

namespace XML_Et_CSharp_Initiation  La solution


{
public partial class Exemple_1 : Form
{
public XmlDocument document = new XmlDocument();

65 / 90
public XmlNodeList menus;

private void Exemple_1_Load( . . . )


{
document.Load(@"Chemin\resto.xml");
menus = document.GetElementsByTagName("menu");

foreach (XmlNode unMenu in menus)

LstMenus.Items.Add(unMenu.Attributes["type"].Value);

}
}
}

 Exemple 2 : Ajout d’un attribut au nœud « menu ». Et sa suppression.

Les caractéristiques des nœuds peuvent également être modifiées en y ajoutant un


attribut. Les nœuds «menu» peuvent par exemple recevoir un attribut prix .
On peut aussi le supprimer.

 Code C# :

using System.Xml;

namespace XML_Et_CSharp_Initiation
{
public partial class Exemple_2 : Form
{

public XmlDocument document = new XmlDocument();


66 / 90
public XmlNodeList menus;

private void Exemple_2_Load( . . . )


{

document.Load(@"Chemin\resto.xml");
menus = document.GetElementsByTagName("menu");

private void CmdAjouterAttribut_Click( . . . )


{

XmlAttribute att;

foreach (XmlNode unMenu in menus)


{
if (unMenu.Attributes["type"].Value == "gastronomique")
{
att = document.CreateAttribute("prix");
att.Value = "50";
unMenu.Attributes.Append(att);
}

if (unMenu.Attributes["type"].Value == "economique")
{
att = document.CreateAttribute("prix");
att.Value = "15";
unMenu.Attributes.Append(att);
}

// Enregistrer les modification dans le fichier XML


//document.Save(@"Chemin\resto.xml");

foreach (XmlNode unMenu in menus)


LstMenus.Items.Add(unMenu.OuterXml);

private void CmdSupprimerAttribut_Click( . . . )


{

foreach (XmlElement unMenu in menus)


{
unMenu.RemoveAttribute("prix");
}

LstMenus.Items.Clear();

67 / 90
foreach (XmlNode unMenu in menus)
LstMenus.Items.Add(unMenu.OuterXml);

// Enregistrer les modification dans le fichier XML


//document.Save(@"Chemin\resto.xml");

}
}
}

 Exemple 3 : Ajout de nœuds enfants à des nœuds de l’arborescence.

Il est également possible d’ajouter des nœuds enfants à des nœuds existant
dans l’arborescence, en créant des instances de la classe XmlNode et en les reliant à leur
nœud parent. L’exemple suivant ajoute un digestif au menu gastronomique.

 Code C# :

using System.Xml;

namespace XML_Et_CSharp_Initiation
{
public partial class Exemple_3 : Form
{

68 / 90
public XmlDocument document = new XmlDocument();
public XmlNodeList menus;

private void Exemple_3_Load( . . . )


{

document.Load(@"Chemin\resto.xml");
menus = document.GetElementsByTagName("menu");

private void CmdAjouterNoeud_Click( . . . )


{
LstMenus.Items.Clear();
foreach ( XmlNode unMenu in menus)
{
if ( unMenu.Attributes["type"].Value == "gastronomique" )
{
XmlNode n1, n2, n3;
n1 = document.CreateNode(XmlNodeType.Element, "digestif", "");
n2 = document.CreateNode(XmlNodeType.Element, "nom", "");
n3 = document.CreateNode(XmlNodeType.Text, "", "" );
n3.Value = "Thé";
n2.AppendChild(n3);
n1.AppendChild(n2);
unMenu.AppendChild(n1);

LstMenus.Items.Add(unMenu.LastChild.PreviousSibling.OuterXml);
LstMenus.Items.Add(unMenu.LastChild.OuterXml);
}
}
}

private void CmdSupprimerNoeud_Click( . . . )


{

LstMenus.Items.Clear();
foreach (XmlNode unMenu in menus)
{
if (unMenu.Attributes["type"].Value == "gastronomique")
{
unMenu.RemoveChild(unMenu.LastChild);
LstMenus.Items.Add(unMenu.LastChild.OuterXml);
}
}
}
}
}

 Sauvegarde du document XML :

En fait, seule la représentation en mémoire du document XML est modifiée. Si

69 / 90
vous souhaitez conserver les modifications, il faut enregistrer le document dans un fichier
pour assurer la persistance des informations. Pour cela, vous devez utiliser la méthode
save de la classe XmlDocument, en lui fournissant le nom du fichier dans lequel vous
souhaitez effectuer la sauvegarde :

document.Save(@"Chemin\resto.xml");

II - Utilisation de XPath

L’objectif principal de XPath est de définir la manière d’adresser des parties d’un
document XML. Le nom XPath vient de l’utilisation d’une écriture de type “path”. Le but est
de se déplacer à l’intérieur de la structure hiérarchique d’un document XML comme dans une
arborescence de répertoires. Pour avoir une idée de l’intérêt de XPath, nous pourrions dire
qu’il est l’équivalent du langage SQL pour un document XML.

LINQ to XML

I - Présentation

70 / 90
LINQ to XML, aussi appelé XLinq permet d’établir des requêtes sur du XML. Dans le
but d’utiliser LINQ to XML, il est utile d’ajouter la librairie « System.Xml.Linq».

II - Les différentes classes de LINQ to XML

Pour commencer, nous allons apprendre à nous servir de XLinq et plus précisément
de ses classes. Contrairement au XML où les classes sont préfixées de «Xml», dans LINQ
to XML celles-ci sont préfixées de «X». Par exemple, «XmlDocument»
devient «XDocument», «XmlElement» devient «XElement», etc.

«XDocument» correspond au document XML. «XElement», lui, correspond à un nœud.

II - 1 «XDocument» et «XElement»

 Exemple : Creation d’un document XML.

XDocument document = new XDocument(


new XElement("Racine",
new XElement("Fils1", "Contenu1"),
new XElement("Fils2",
new XElement("Fils2-1","Contenu2-1")),
new XElement("Fils3", "Contenu3")));
Console.WriteLine(document);

II - 2 «XAttribute» et «XComment»

 Exemple : Creation d’un document XML.

XDocument document = new XDocument(


new XElement("Racine",
new XAttribute("id","valeur"),
new XElement("Fils1", "Contenu1"),
new XElement("Fils2",
new XAttribute("ID", "0"),
new XElement("Fils2-1","Contenu2-1")),
new XComment("Voici un commentaire"),
new XElement("Fils3", "Contenu3")));
Console.WriteLine(document);
document.Save(@"Chemin\Test.xml");
Console.Read();

II – 3 Chargement du fichier XML

Pour charger un fichier XML et commencer à l’utiliser, nous avons deux possibilités :

 créer une variable de type XDocumentet charger le fichier ;


 créer une variable de type XElementet charger le fichier.
71 / 90
Première possibilité :
XDocument xml;
……
xml = XDocument.Load("resto.xml");

Deuxième possibilité :
XElement xml;
……
xml = XElement.Load("resto.xml");

La différence se situe ici :

 avec la variable de type XDocument, il faut d’abord commencer par la balise racine
qu’est «restaurant» pour utiliser le fichier XML;
 avec la variable de type XElement, on accède directement aux balises «menu».

private void button5_Click(object sender, EventArgs e)


{
doc.Save(Application.StartupPath + @"\employees.xml");
}

72 / 90
Table 4-6.Examples of XPath Expressions

Purpose Expression
To select an employee whose employee
employees/employee[@employeeid=1]
ID is 1
To select the employee whose first name
employees/employee[firstname/text()='Andrew']
is Andrew
To select the last employee from the
employees/employee[last()]
document
To select the employee whose index is 2 employees/employee[position()=2]
To select an employee whose name
employees/employee[contains(firstname,'Nancy')]
contains Nancy
To select the name of the first employee employees/employee/firstname[text()]

73 / 90
Gestion du fichier XML Client.xml avec C #

private void CmdSupprimer_Click( . . . )


{
xElt = elt.PreviousSibling;
document.DocumentElement.RemoveChild(elt);
elt = xElt;
Afficher(elt);

// Ecriture du Xml
document.Save(@"Chemin\Clients.xml");
MessageBox.Show("Suppression réussi");
}

private void CmdModifier_Click( . . . )


{
xElt = elt;
elt.Attributes[0].Value = Txt_Id.Text;
elt.ChildNodes[0].InnerText = Txt_Nom.Text;
elt.ChildNodes[1].InnerText = Txt_Prenom.Text;
elt.ChildNodes[2].InnerText = Txt_Ville.Text;
elt.ChildNodes[3].InnerText = Txt_Tel.Text;
document.DocumentElement.ReplaceChild(elt,xElt);
// Ecriture du Xml
document.Save(@"Chemin\Clients.xml");

private void CmdRechercher_Click( . . . )


{
XPathNodeIterator noeuds =
navigateur.Select("/Clients/Client [@id='" + TxtRechercher.Text + "']");

while (noeuds.MoveNext())
{
//elt = noeuds.MoveNext;
Lst1.Items.Add(noeuds.Current.OuterXml);

74 / 90
}
Lst1.Items.Add(elt.OuterXml);
//elt = noeuds.MoveNext().;

75 / 90
public partial class Form1 : Form
{
ds1 ds = new ds1();
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
ds.WriteXml("Client.xml");
ds.WriteXmlSchema("Client.xsd");

}
}

76 / 90
Using LINQ to SQL (Part 1)
Saturday, May 19, 2007
.NET ASP.NET Data LINQ Visual Studio
Over the last few months I wrote a series of blog posts that covered some of the new language
features that are coming with the Visual Studio and .NET Framework "Orcas" release. Here are
pointers to the posts in my series:

 Automatic Properties, Object Initializer and Collection Initializers


 Extension Methods
 Lambda Expressions
 Query Syntax
 Anonymous Types

The above language features help make querying data a first class programming concept. We
call this overall querying programming model "LINQ" - which stands for .NET Language
Integrated Query.

Developers can use LINQ with any data source. They can express efficient query behavior in
their programming language of choice, optionally transform/shape data query results into
whatever format they want, and then easily manipulate the results. LINQ-enabled languages
can provide full type-safety and compile-time checking of query expressions, and development
tools can provide full intellisense, debugging, and rich refactoring support when writing LINQ
code.

77 / 90
LINQ supports a very rich extensibility model that facilitates the creation of very efficient
domain-specific operators for data sources. The "Orcas" version of the .NET Framework ships
with built-in libraries that enable LINQ support against Objects, XML, and Databases.

What Is LINQ to SQL?

LINQ to SQL is an O/RM (object relational mapping) implementation that ships in the .NET
Framework "Orcas" release, and which allows you to model a relational database using .NET
classes. You can then query the database using LINQ, as well as update/insert/delete data
from it.

LINQ to SQL fully supports transactions, views, and stored procedures. It also provides an easy
way to integrate data validation and business logic rules into your data model.

Modeling Databases Using LINQ to SQL:

Visual Studio "Orcas" ships with a LINQ to SQL designer that provides an easy way to model
and visualize a database as a LINQ to SQL object model. My next blog post will cover in more
depth how to use this designer (you can also watch this video I made in January to see me
build a LINQ to SQL model from scratch using it).

Using the LINQ to SQL designer I can easily create a representation of the sample "Northwind"
database like below:

78 / 90
My LINQ to SQL design-surface above defines four entity classes: Product, Category, Order and
OrderDetail. The properties of each class map to the columns of a corresponding table in the
database. Each instance of a class entity represents a row within the database table.

The arrows between the four entity classes above represent associations/relationships between
the different entities. These are typically modeled using primary-key/foreign-key relationships
in the database. The direction of the arrows on the design-surface indicate whether the
association is a one-to-one or one-to-many relationship. Strongly-typed properties will be
added to the entity classes based on this. For example, the Category class above has a one-to-
many relationship with the Product class. This means it will have a "Categories" property which
is a collection of Product objects within that category. The Product class then has a "Category"
property that points to a Category class instance that represents the Category to which the
Product belongs.

The right-hand method pane within the LINQ to SQL design surface above contains a list of
stored procedures that interact with our database model. In the sample above I added a single
"GetProductsByCategory" SPROC. It takes a categoryID as an input argument, and returns a
sequence of Product entities as a result. We'll look at how to call this SPROC in a code sample
below.
79 / 90
Understanding the DataContext Class

When you press the "save" button within the LINQ to SQL designer surface, Visual Studio will
persist out .NET classes that represent the entities and database relationships that we
modeled. For each LINQ to SQL designer file added to our solution, a custom DataContext
class will also be generated. This DataContext class is the main conduit by which we'll query
entities from the database as well as apply changes. The DataContext class created will have
properties that represent each Table we modeled within the database, as well as methods for
each Stored Procedure we added.

For example, below is the NorthwindDataContext class that is persisted based on the model we
designed above:

LINQ to SQL Code Examples

Once we've modeled our database using the LINQ to SQL designer, we can then easily write
code to work against it. Below are a few code examples that show off common data tasks:

1) Query Products From the Database


The code below uses LINQ query syntax to retrieve an IEnumerable sequence of Product
objects. Note how the code is querying across the Product/Category relationship to only
retrieve those products in the "Beverages" category:

80 / 90
C#:

VB:

2) Update a Product in the Database


The code below demonstrates how to retrieve a single product from the database, update its
price, and then save the changes back to the database:

C#:

VB:

Note: VB in "Orcas" Beta1 doesn't support Lambdas yet. It will, though, in Beta2 - at which point
the above query can be rewritten to be more concise.

3) Insert a New Category and Two New Products into the Database
The code below demonstrates how to create a new category, and then create two new
products and associate them with the category. All three are then saved into the database.

81 / 90
Note below how I don't need to manually manage the primary key/foreign key
relationships. Instead, just by adding the Product objects into the category's "Products"
collection, and then by adding the Category object into the DataContext's "Categories"
collection, LINQ to SQL will know to automatically persist the appropriate PK/FK relationships
for me.

C#

VB:

4) Delete Products from the Database


The code below demonstrates how to delete all Toy products from the database:

82 / 90
C#:

VB:

5) Call a Stored Procedure


The code below demonstrates how to retrieve Product entities not using LINQ query syntax,
but rather by calling the "GetProductsByCategory" stored procedure we added to our data
model above. Note that once I retrieve the Product results, I can update/delete them and then
call db.SubmitChanges() to persist the modifications back to the database.

C#:

VB:

83 / 90
6) Retrieve Products with Server Side Paging
The code below demonstrates how to implement efficient server-side database paging as part
of a LINQ query. By using the Skip() and Take() operators below, we'll only return 10 rows from
the database - starting with row 200.

C#:

VB:

Summary

LINQ to SQL provides a nice, clean way to model the data layer of your application. Once
you've defined your data model you can easily and efficiently perform queries, inserts, updates
and deletes against it.

Hopefully the above introduction and code samples have helped whet your appetite to learn
more. Over the next few weeks I'll be continuing this series to explore LINQ to SQL in more
detail.
84 / 90
Hope this helps,

Scott

What Is LINQ To SQL?


Full meaning of LINQ is ‘Language Integrated Query’, which replaces the traditional sql query
execution process. Moreover, it doesn’t only applicable to manipulate database results, but it
can also be used to manipulates array/list collections. LinQ was released as part of the .NET
framework 3.0 and can be used from languages supported by .NET framework like C#, VB etc.
The term ‘LINQ To SQL‘ refers to the technology by which we can use LINQ for access SQL
Databases. Here in this tutorial, I will show step by step ways to get started with LINQ To SQL
programming with C#.

Read All LinQ Tutorials By CodeSamplez.com

85 / 90
Mapping LINQ To SQL Class From SQL Server
Database:
First step to be able to use LinQ on our SQL database, we will need to define a way, by
which .NET can recognize the database as Classes/Objects, so we will need to map the
database tables/stored procedures to LinQ to SQL classes. To accomplish this task
successfully, first open your project in the solution explorer, right click->add->new item, in the
‘data’ categories, there is a type named ‘LINQ To SQL Classes’. Select that. We will get
a .dbml file created along with designer interface.

The designer interface has two-part, one for dragging tables from server explorer(to create
classes from tables automatically), another is for methods where we can drag stored
procedures etc. After dragging all classes from server explorer, we are done. Here is a sample
db structure that we will be using on the way of this tutorial:

Select Data Using LinQ To SQL:


After we make the DBML files appropriately, it’s very simple to get started our actually
implementation in c# code. Most interesting thing is, we will be using sql query like syntax right from
the c# code for getting database results. Suppose, we are trying to validate a user against a given
username/password from database. Here is a sample codes of a function for such purpose:

86 / 90
1
public bool IsValidUser(string userName, string passWord)
2 {
3 DBNameDataContext myDB = new DBNameDataContext();
4 var userResults = from u in myDB.Users
5 where u.Username == userName
6 && u.Password == passWord
select u;
7 return Enumerable.Count(userResults) > 0;
8 }
9
You can see, the syntax is much like sql, but not exactly same though. First, when you create a
new dbml file with name ‘DBName.dbml’, there is created a corresponding DataContext class
in .net and named something like ‘DBNameDataContext’ (These DataContext classes are now
responsible for .NET To Database communications) . In the linq query syntax, this object will
be used to present the database.

Next, whenever we write something like “from u in myDB.Users” visual studio automatically
treat ‘u’ as an object of User class, that actually represents database’s ‘users’ table(you will
might also notice if your database table contains plural form like ‘users’, it automatically makes
it as singular when creating the linq to sql class like ‘User’, though table name used in the
query will still be plural).

Next, notice one of the most useful advantage of LINQ, if you make any kind of data type
mistake in your code, you will be notified immediately while compiling your project. This will
saves lots of your debugging time and lessen the db errors at the same time. its possible here
as now all you are using are acting like a .NET class, so its simply validating the property’s
data type. Of course, you will have to remember that, if you change your db structure/column
data type etc later on, you should have to drag the tables from server explorer to dbml once
again to reflect your db changes to the linq to sql classes.

Next, Note the result is assigned to a variable of type ‘var‘. This data type is also new from
.NET framework 3.0 and used to represent data with dynamic types. That means, here any
kind of data returned from the linq query will be assigned to that variable and you will have to
just cast that to the proper data type.

Next, “Enumerable.Count“, this function count the number of rows(Or number of objects)
returned by the query. You can use this function on ‘var’ type result object without need of
casting it to any intermediate form.

Select Operation Without SQL Syntax in LinQ:

87 / 90
The above example showed how to use LinQ To SQL syntax for querying database for retrieve
data. However, there is alternative simple ways also for avoid using query like syntax by using
integrated ‘Where’ method. Here is a simple code example to accomplish that:

01
02 public bool IsValidUser(string userName, string passWord)
{
03 DBNameDataContext myDB = new DBNameDataContext();
04 List<User> users = myDB.Users.Where(u => u.Username == userName && u.Password=
05 if(users.Count>0)
06 {
return true;
07 }
08 return false;
09 }
10
Retrieve A Single Row With LinQ:
On the above example, we have learned to execute a SQL like statement. However, LINQ
provides much more flexibility than that. Like, if you need a single item/row from database
table, it can be done very easily. Here is a code sample for such cases:

1 public User GetUser(string userName)


2 {
3 DBNameDataContext myDB = new DBNameDataContext();
4 User user = myDB.Users.Single(u, u.UserName=>userName);
return user;
5 }
6
The above example will return a single record from database table. In the
“u.UserName=>userName” part, you can mention any column name you want to be validated.

‘Foreach’ Loop Through All LinQ To SQL Returned


Results:
In case, when LinQ query returns multiple results, we often need to traverse through all the
result rows(here all LinQ objects) and process in some way. It can be done very easily with
a foreach loop. Although for loop also can be used, however foreach is better in
performance(to know details, you can refer to my for vs foreach article). here is the code samples
for using the foreach loop for traversing through all result objects:

1 foreach(User user in userResults)


{
2 //checking the result as like object
3 if(user.Role == 'admin')
4 {
5 //do whatever you need
6 }

88 / 90
7 }
8

89 / 90
ANNEXES

I - Enregistrer un dataGridView dans un fichier XML.docx

private void CmdToFichierXML_Click(object sender, EventArgs e)


{

// Cas ou on travaille en Deconnecté


//var dt = ((DataTable)dgv.DataSource).Copy();
//DataSet ds = new DataSet();
//ds.Tables.Add(dt);
//dt.WriteXml(@"E:\DataGrid.xml", XmlWriteMode.IgnoreSchema);

DataSet ds = new DataSet("Commandes");


DataTable dt = new DataTable("Commande");
dt.Columns.Add("NumCom");
dt.Columns.Add("DateCom");
dt.Columns.Add("CodeCl");

foreach (DataGridViewRow row in dgv.Rows) {


DataRow dr = dt.NewRow();
dr[0] = row.Cells[0].Value;
dr[1] = row.Cells[1].Value;
dr[2] = row.Cells[2].Value;
dt.Rows.Add(dr);
}

ds.Tables.Add(dt);
ds.WriteXml(@"E:\DataGrid.xml"); // XmlWriteMode.IgnoreSchema);

private void CmdToDataGridView_Click(object sender, EventArgs e)


{
// Affichage d'un fichier XML dans un DataGridView
DataSet ds = new DataSet();
ds.ReadXml(@"E:\Livres.xml");
dgv.DataSource = ds.Tables[0];
}

90 / 90