Beruflich Dokumente
Kultur Dokumente
Module 09 :
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.
ClientBS.AddNew();
ClientActuel.CodeCl = TxtCodeCl.Text;
ClientActuel.Nom = TxtNom.Text;
ClientActuel.Ville = TxtVille.Text;
ClientBS.EndEdit(); Enregistre dans ClientBS et la table 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
2 / 90
2 - Recherche et navigation avec la classe BindingSource :
a) Navigation :
ClientBS.MoveFirst ();
ClientBS.MoveNext ();
ClientBS.MovePrevious();
ClientBS.MoveLast();
b) Recherche :
Syntaxe :
ClientBS. Find(“CodeCl”, TxtRechercher.Text);
c) Affichage :
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()
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 :
Et on n’a plus besoin d’une procédure Afficher() pour afficher les lignes du
BindingSource dans les TextBoxs du formulaire.
dc.Client.InsertOnSubmit(cl) ;
dc.SubmitChanges();
dc.Client.InsertAllOnSubmit(ListClient) ;
dc.SubmitChanges();
II – Navigation et recherche :
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 …
Code C# :
dgv1.DataSource = Clients;
}
}
6 / 90
Requêtes Linq To SQL
(Expressions λ (Lambda) et LinqPad)
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)
8 / 90
I – Requêtes Linq appliquées sur les tables du DataContext.
1) TOP (N)
2) TOP (N)
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;
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)
A ce stade, l’utilisateur Ali n’a aucun droit sur la base de données Vente.
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.
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 :
dr = CmdSelect.ExecuteReader();
L’utilisateur Ali_U n’a pas le droit d’exécuter Select sur la table Client.
12 / 90
CmdInsert.ExecuteNonQuery();
L’utilisateur Ali n’a pas le droit d’exécuter INSERT sur la table Client.
CmdUpdate.ExecuteNonQuery();
L’utilisateur Ali_U n’a pas le droit d’exécuter UPDATE sur la table Client.
CmdDelete.ExecuteNonQuery();
L’utilisateur Ali_U n’a pas le droit d’exécuter DELETE sur la table Client.
I - Conditions préalables :
<startup useLegacyV2RuntimeActivationPolicy="true">
Puis, enregistrez.
App.config :
14 / 90
II – Démarche pour la création d’un rapport Crystal :
15 / 90
Taper un nom et Ciquer sur Ajouter.
16 / 90
Déploiement d’une application :
Conditions préalables :
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);
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)
};
Compiled Queries
var findMovieByIDQuery =
CompiledQuery.Compile(
(MovieReviewDataContext dc, int movieID) =>
(from movie in dc.Movies
where movie.ID == movieID
select movie).FirstOrDefault()
);
19 / 90
Executing SQL
var moreMovies =
ctx.ExecuteQuery<Movie>(
"SELECT * FROM movies WHERE movie_id< {0}", 10);
Query Examples
https://msdn.microsoft.com/en-us/library/bb386962(v=vs.110).aspx
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
};
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 };
Aggregate Seed
Count
static void Sample_Count_Lambda()
{
string[] names = { "Peter", "John", "Kathlyn", "Allen", "Tim" };
Max
22 / 90
var result = numbers.Max();
Min
Sum
Average
Debug.WriteLine("Average is:");
23 / 90
Debug.WriteLine(result);
}
Output:
Average is:
10.5
ElementAt
ElementAtOrDefault
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" };
First Conditional
FirstOrDefault
25 / 90
True
Last
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 = { };
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
Join
27 / 90
string[] europeanCountries = { "Denmark", "Germany", "Italy", "Portugal", "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; }
}
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
OrderBy
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; }
}
30 / 90
Ben
31 / 90
Beijing
32 / 90
6
33 / 90
Debug.WriteLine(word);
}
Output:
Skips words while the condition is met:
three
four
five
six
34 / 90
4
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
35 / 90
});
37 / 90
20
25
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
38 / 90
var result = numbers.Distinct();
39 / 90
Output:
Intersect creates a single sequence with only the duplicates:
3
40 / 90
static void Sample_ToList_Lambda()
{
string[] names = { "Brenda", "Carl", "Finn" };
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:
where n.Contains("Q")
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();
}
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();
}
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; }
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
@codecl varchar(6),
@nom varchar(40) output,
@ville varchar(30) output
AS
Select @nom=Nom,@ville=Ville From client Where Codecl=@codecl
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 MajClient_AvecPS()
{
InitializeComponent();
}
else
{
con.Open();
CmdMaj.CommandText = "PS_InsertCl";
SqlParameter paramCodeCl = new
SqlParameter("@CodeCl", SqlDbType.VarChar,6);
paramCodeCl.Direction = ParameterDirection.Input;
paramCodeCl.Value = TxtCodeCl.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;
}
}
51 / 90
con.Open();
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();
con.Open();
CmdMaj.CommandText = "PS_UpdateCl";
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();
CmdMaj.Parameters.Add(paramCodeCl);
CmdMaj.ExecuteNonQuery();
CmdMaj.Parameters.Clear();
con.Close();
}
}
}
53 / 90
}
*************************************************
//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.";
}
***************************************************
Before going on to discuss the detail of maintaining Transaction, it should be made clear that
LINQ to SQL implicitly maintain transaction
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.
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.
Now begin the transaction and assign it to transaction object created in first step.
transaction = dataContext.Connection.BeginTransaction();
dataContext.Transaction = transaction;
In the try block add the logic to insert the data into the and just after SubmitChanges() add
transaction.Commit();
transaction.Rollback();
try
{
Table2 tbl2 = new Table2()
{
ID = 1,
Value = "Test Data"
};
dataContext.Table2s.InsertOnSubmit(tbl2);
dataContext.TestTables.InsertOnSubmit(tstTbl);
dataContext.SubmitChanges();
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
Console.WriteLine("Rolback Done");
}
finally
{
if (null != dataContext.Connection)
{
dataContext.Connection.Close();
}
}
}
*******************************************************
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
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
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,
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
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,
(ConfigurationManager.ConnectionStrings
[Constants.ConnectionString].ConnectionString);
try
// Nullable data type as the methods generated for SP will use Nullable
// type
objDataClass.Connection.Open();
trans = objDataClass.Connection.BeginTransaction();
// All the database operation perform by this object will now use
//transaction
objDataClass.Transaction = trans;
// Insert Category
objDataClass.InsertCategory
ref intCategoryID,
txtName.Text.Trim().Replace(“‘”, “””),
txtDescription.Text.Trim().Replace(“‘”, “””),
new byte[0]
);
// Insert Product
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();
// Rollback transaction
if (trans != null)
trans.Rollback();
finally
if (objDataClass.Connection.State == ConnectionState.Open)
objDataClass.Connection.Close();
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.
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.
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)
60 / 90
//OBJECT OF TABLE IN DATABASE (DRAGED IN DATA CONTEXT CLASS)
Prod.Field1 = 1001;
Prod.Field2 = "My new Product";
Prod.Field3 = "This is new product";
Prod.Field4 = 10.00;
Prod.Field5 = 500;
DataContexClassObject.Product_Master.InsertOnSubmit(Prod);
DataContexClassObject.SubmitChanges();
DataContexClassObject.Order_Book.InsertOnSubmit(OrderUpdate);
DataContexClassObject.SubmitChanges();
dcCSE.SubmitChanges();
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>
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.
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) :
<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
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.
Code C# :
using System.Xml;
65 / 90
public XmlNodeList menus;
LstMenus.Items.Add(unMenu.Attributes["type"].Value);
}
}
}
Code C# :
using System.Xml;
namespace XML_Et_CSharp_Initiation
{
public partial class Exemple_2 : Form
{
document.Load(@"Chemin\resto.xml");
menus = document.GetElementsByTagName("menu");
XmlAttribute att;
if (unMenu.Attributes["type"].Value == "economique")
{
att = document.CreateAttribute("prix");
att.Value = "15";
unMenu.Attributes.Append(att);
}
LstMenus.Items.Clear();
67 / 90
foreach (XmlNode unMenu in menus)
LstMenus.Items.Add(unMenu.OuterXml);
}
}
}
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;
document.Load(@"Chemin\resto.xml");
menus = document.GetElementsByTagName("menu");
LstMenus.Items.Add(unMenu.LastChild.PreviousSibling.OuterXml);
LstMenus.Items.Add(unMenu.LastChild.OuterXml);
}
}
}
LstMenus.Items.Clear();
foreach (XmlNode unMenu in menus)
{
if (unMenu.Attributes["type"].Value == "gastronomique")
{
unMenu.RemoveChild(unMenu.LastChild);
LstMenus.Items.Add(unMenu.LastChild.OuterXml);
}
}
}
}
}
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».
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.
II - 1 «XDocument» et «XElement»
II - 2 «XAttribute» et «XComment»
Pour charger un fichier XML et commencer à l’utiliser, nous avons deux possibilités :
Deuxième possibilité :
XElement xml;
……
xml = XElement.Load("resto.xml");
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».
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 #
// Ecriture du Xml
document.Save(@"Chemin\Clients.xml");
MessageBox.Show("Suppression réussi");
}
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();
}
}
}
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:
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.
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.
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:
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:
80 / 90
C#:
VB:
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:
82 / 90
C#:
VB:
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
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:
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.
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:
88 / 90
7 }
8
89 / 90
ANNEXES
ds.Tables.Add(dt);
ds.WriteXml(@"E:\DataGrid.xml"); // XmlWriteMode.IgnoreSchema);
90 / 90