Overblog Suivre ce blog
Administration Créer mon blog

Présentation

  • : Romagny13 - Du .NET,du pur .NET
  • Romagny13 - Du .NET,du pur .NET
  • : Cycle de progression Faire (quelque chose qui marche) -> comprendre ce que l’on fait/comment cela marche -> pousser plus loin les notions
  • Contact

Recherche

Articles Récents

2 février 2014 7 02 /02 /février /2014 01:39

binding5-copie-2.png

 

 

On crée un constructeur dans la form détail qui reçoit le bindingSource de la form de départ

FListClient

public partial class FListClient : Form

    {

        public FListClient()

        {

            InitializeComponent();

        }

 

        DataSet dataSet;

        SqlConnection connection;

        SqlDataAdapter clientAdapter;

        BindingSource bindingSource;

 

        private void FListClient_Load(object sender, EventArgs e)

        {

            dataSet = new DataSet();

            connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=True");

 

            clientAdapter = new SqlDataAdapter("Select * from [dbo].[Client]", connection);

            dataSet.Tables.Add(new DataTable("Client"));

            clientAdapter.Fill(dataSet.Tables["Client"]);

 

            bindingSource = new BindingSource();

            bindingSource.DataSource = dataSet;

            bindingSource.DataMember = "Client";

            bindingSource.BindingComplete += bindingSource_BindingComplete;

 

            clientDataGridView.DataSource = bindingSource;

        }

 

        void bindingSource_BindingComplete(object sender, BindingCompleteEventArgs e)

        {

            if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate && e.Exception == null)

                e.Binding.BindingManagerBase.EndCurrentEdit();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            FDetailClient detailForm = new FDetailClient(bindingSource);

            detailForm.Show();

        }

 

    }

 

FDetailClient

public partial class FDetailClient : Form

    {

        private BindingSource bindingSource;

 

        public FDetailClient()

        {

            InitializeComponent();

        }

 

        private BindingSource bindingSourceFDetail;

 

        public FDetailClient(BindingSource bindingSourceFList)

        {

            InitializeComponent();

 

            bindingSourceFDetail = bindingSourceFList;

 

            lblClientId.DataBindings.Add("Text", bindingSourceFDetail, "Id",true);

            txtClientName.DataBindings.Add("Text", bindingSourceFDetail, "Name");

            txtClientEmail.DataBindings.Add("Text", bindingSourceFDetail, "Email");

 

 

 

            // on remplit la comboBox avec la liste des catégories                     

            DataSet dataSet = new DataSet();

            SqlDataAdapter categoryAdapter = new SqlDataAdapter("Select * from [dbo].[Category]", new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=True"));

            dataSet.Tables.Add(new DataTable("Category"));

            categoryAdapter.Fill(dataSet.Tables["Category"]);

            cboClientCategory.DataSource = dataSet;

            cboClientCategory.DisplayMember = "Category.Name";

            cboClientCategory.ValueMember = "Category.Id";

            cboClientCategory.DataBindings.Add("SelectedValue", bindingSourceFDetail, "CategoryId");

 

       

        }    

}

         


 

 

 

  Astuces  

Supprimer des colonnes du DatagridView

// supprimer des colonnes inutiles du DatagridView

 clientDataGridView.Columns.Remove("Id");

 clientDataGridView.Columns.Remove("CategoryId");

 

 

Ajouter une DataGridViewComboBoxColumn liée aux données

binding6.png  

 

DataGridViewComboBoxColumn cboClientCategory = new DataGridViewComboBoxColumn();

          

// 1 on crée un BindingSource avec pour DataSource la table Category

BindingSource categoryBindingSource = new BindingSource();

categoryBindingSource.DataSource = dataSet;

categoryBindingSource.DataMember = "Category";

 

// 2 on affecte le bindingSource à la DataGridViewComboBoxColumn

cboClientCategory.DataSource = categoryBindingSource;

// lié à la propriété/clé étrangère CategoryId de la table Client

cboClientCategory.DataPropertyName = "CategoryId";

// on affiche la propriété Name de la table Category dans la DataGridViewComboBoxColumn

cboClientCategory.DisplayMember = "Name";

// ValueMemeber est réglé sur la clé primaire Id de la table Category

cboClientCategory.ValueMember = "Id";

clientDataGridView.Columns.Add(cboClientCategory);                    

 

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:38

1– DataBinding ComboBox, label/textBox

  binding3a

ComboBox

// On peut également afficher la liste des catégories dans une comboBox par exemple

// en changeant la catégorie sélectionnée le binding se fera automatiquement et la liste des clients pour cette catégorie sera listée dans le datagridView

cboCategories.DataSource = dataSet;

cboCategories.DisplayMember = "Category.Name";

cboCategories.ValueMember = "Category.Id";

 

Remplir une comboBox avec la liste des noms de catégories et sélectionner la catégorie du Client,sachant que ce client a une clé étrangère Categoryd(int)

// on remplit la comboBox avec la liste des catégories .On affiche la propriété Name, et en SelectedValue on réupérera l'Id

cboClientCategory.DataSource = dataSet;

cboClientCategory.DisplayMember = "Category.Name";

cboClientCategory.ValueMember = "Category.Id";

// à partir de la clé étrangère CategoryId de la table Client(elle est de type int) on sélectionne la catégorie

cboClientCategory.DataBindings.Add("SelectedValue", dataSet, "Client.CategoryId");          

 

Label

//on peut aussi afficher dans un label : la propriété Text le nom de la table Category du dataSet

lblCategoryId.DataBindings.Add("Text",dataSet,"Category.Name");

// autre exemple on affiche l'id de la catégorie correspondant la valeur courante de la comboBox(affichera "2" par exemple)

lblCategoryId.DataBindings.Add("Text", cboCategories, "SelectedValue");                    

 

2-Afficher le détail

binding4-copie-1.png  

J’utilise un BindingSource qui permet de mettre à jour facilement l’UI .

Avec un DataSet typé il est possible d’appeler la méthode AcceptChanges() pour valider les changements dans le dataSet et mettre à jour l’UI .

La méthode HasChanges() du dataSet permet de savoir si des modifications ont été apportées dans celui-ci

Il existe également le control BindingNavigator qui peut être utile pour la navigation et les actions de base .

   SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=True");

        DataSet dataSet = new DataSet();

        SqlDataAdapter categoryAdapter;

        SqlDataAdapter clientAdapter;

        BindingSource clientBindingSource;

 

        private void FDetail_Load(object sender, EventArgs e)

        {

 

            categoryAdapter = new SqlDataAdapter("Select * from [dbo].[Category]", connection);

            dataSet.Tables.Add(new DataTable("Category"));

            categoryAdapter.Fill(dataSet.Tables["Category"]);

 

 

            clientAdapter = new SqlDataAdapter("Select * from [dbo].[Client]", connection);

            dataSet.Tables.Add(new DataTable("Client"));

            clientAdapter.Fill(dataSet.Tables["Client"]);

 

            clientBindingSource = new BindingSource();

            clientBindingSource.DataSource = dataSet;

            clientBindingSource.DataMember = "Client";

 

            clientDataGridView.DataSource = clientBindingSource;

 

            lblClientId.DataBindings.Add("Text", clientBindingSource, "Id");

            txtClientName.DataBindings.Add("Text", clientBindingSource, "Name");

            txtClientEmail.DataBindings.Add("Text", clientBindingSource, "Email");

 

            cboClientCategory.DataSource = dataSet;

            cboClientCategory.DisplayMember = "Category.Name";

            cboClientCategory.ValueMember = "Category.Id";

 

            cboClientCategory.DataBindings.Add("SelectedValue", clientBindingSource, "CategoryId");

 

 

Validation et mise à jour de la base

Valider les changements au niveau du dataSet(la base de données n’est pas modifiée ici,seule le dataSet et l’UI est mise à jour)

private void button1_Click(object sender, EventArgs e)

        {

            this.Validate();

            clientBindingSource.EndEdit();

        }

 

Mise à jour de la base (cas on a modifié un client)

  private void UpdateClient()

        {

            try

            {

                clientAdapter.UpdateCommand = new SqlCommand(@"UPDATE [dbo].[Client]

                                                            SET [Name] = @Name, [Email] = @Email, [CategoryId] = @CategoryId

                                                            WHERE Id = @Id", connection);

                clientAdapter.UpdateCommand.CommandType = CommandType.Text;

                clientAdapter.UpdateCommand.Parameters.Add(new SqlParameter("@Name", SqlDbType.Char, 0, ParameterDirection.Input, 0, 0, "Name", DataRowVersion.Current, false, null, "", "", ""));

                clientAdapter.UpdateCommand.Parameters.Add(new SqlParameter("@Email", SqlDbType.Char, 0, ParameterDirection.Input, 0, 0, "Email", DataRowVersion.Current, false, null, "", "", ""));

                clientAdapter.UpdateCommand.Parameters.Add(new SqlParameter("@CategoryId", SqlDbType.Int, 0, ParameterDirection.Input, 0, 0, "CategoryId", DataRowVersion.Current, false, null, "", "", ""));

                clientAdapter.UpdateCommand.Parameters.Add(new SqlParameter("@Id", SqlDbType.Int, 4, ParameterDirection.Input, 0, 0, "Id", DataRowVersion.Current, false, null, "", "", ""));

 

 

                clientAdapter.Update(dataSet.Tables["Client"]);

            }

            catch (DBConcurrencyException)

            {

                MessageBox.Show("Impossible de mettre à jour.");

            }

        }

}

Et donc il suffit d’appeler la méthode pour valider les changements

private void button1_Click(object sender, EventArgs e)

        {

            this.Validate();

            clientBindingSource.EndEdit();

            UpdateClient() ;

        }

 

Il est possible de s’abonner aux événements  des DataTables tel que RowChanged,ColumnChanged,etc.

dataSet.Tables["Client"].ColumnChanged += FDetail_ColumnChanged;

 

  void FDetail_ColumnChanged(object sender, DataColumnChangeEventArgs e)

        {

          

            // peut permettre de vérifier si la saisie est correcte

            if (string.IsNullOrEmpty(e.ProposedValue.ToString().Trim()) && e.Column.ColumnName=="Name")

            {

                // on peut par exemple utiliser un errorProvider pour une textBox

                errorProvider1.SetError(txtClientName, "Nom nécessaire");

            }

        }

 

Rejeter les changements

La méthode RejectChanges() du dataSet annule les changements de valeur

CancelEdit() du bindingSource permet de mettre à jour l’UI

 

  private void btnCancel_Click(object sender, EventArgs e)

        {

            dataSet.RejectChanges();

            clientBindingSource.CancelEdit();

          

        }

 

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:38

Dans l'exemple j'affiche la liste des clients de la catégorie sélectionnée

 

  binding3.png

 

1-Avec un DataSet Typé

  private dbDemoDataSet dataSet = new dbDemoDataSet();

 

        private void Form1_Load(object sender, EventArgs e)

        {

            SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=True");

 

            // on remplit la table Category du dataset

            CategoryTableAdapter categoryAdapter = new CategoryTableAdapter();

            categoryAdapter.Connection = connection;

            categoryAdapter.Fill(dataSet.Category);

 

            // on remplit la table client du dataset

            ClientTableAdapter clientAdapter = new ClientTableAdapter();

            clientAdapter.Connection = connection;

            clientAdapter.Fill(dataSet.Client);

 

            categoryDataGridView.DataSource = dataSet;

            categoryDataGridView.DataMember = "Category";

 

            // on affiche dans le premier datagridView la liste des catégories

            // et dans le second datagridView la liste des clients de la catégorie sélectionnée dans le premier datagridView

            // syntaxe Tablemere.Nomrelation

            clientDataGridView.DataSource = dataSet;

            clientDataGridView.DataMember = "Category.Client_Category";

        }

 

binding1.png  

 

2-Avec un DataSet

private DataSet dataSet = new DataSet();

 

        private void Form2_Load(object sender, EventArgs e)

        {           

            SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=True");

 

            SqlDataAdapter categoryAdapter = new SqlDataAdapter("Select * from [dbo].[Category]",connection);

            // on crée et ajoute les DataTables au DataSet

            dataSet.Tables.Add(new DataTable("Category"));

            categoryAdapter.Fill(dataSet.Tables["Category"]);

 

 

            SqlDataAdapter clientAdapter = new SqlDataAdapter("Select * from [dbo].[Client]", connection);

            dataSet.Tables.Add(new DataTable("Client"));

            clientAdapter.Fill(dataSet.Tables["Client"]);

 

            // On crée la relation

            dataSet.Relations.Add("Client_Category", dataSet.Tables["Category"].Columns["Id"], dataSet.Tables["Client"].Columns["CategoryId"]);

 

            categoryDataGridView.DataSource = dataSet;

            categoryDataGridView.DataMember = "Category";

 

            clientDataGridView.DataSource = dataSet;

            clientDataGridView.DataMember = "Category.Client_Category";

 

        }

 

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:37

C#,MVVM,Linq/Entiy Framework,Xaml,silverlight,...

http://www.e-naxos.com/AllDotBlog.html

Repost 0
Published by Romagny13 - dans Divers
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:34

Restrictions

Il faut déclarer un tableau de 4 éléments Et affecter la valeur de restriction à la case correspondante . 

Exemple pour ne récupérer que les tables "BASE TABLE"  .Effectivement les "VIEWS" pourraient également être retournées

string[] restrictions = new string[4];

restrictions[3] = "BASE TABLE" ;

 

DataTable tablesSchema = connection.GetSchema("Tables",restrictions);

 

On peut récupérer les schémas des bases de données et pas seulement Sql Server mais également Access, Sql ServerCe ,....

 

http://msdn.microsoft.com/fr-fr/library/cc716722(v=vs.110).aspx  

Repost 0
Published by Romagny13 - dans C
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:34

http://msdn.microsoft.com/fr-fr/library/system.componentmodel.backgroundworker(v=vs.110).aspx

public BackgroundWorker backgroundWorker1;

 

        private void button1_Click(object sender, EventArgs e)

        {

            // Using System.ComponentModel;

            // la variable contenant le nombre d'opérations à effectuer

            int operationCount=Convert.ToInt32(textBox1.Text);

 

            progressBar1.Minimum = 0;

            progressBar1.Step = 1;

            progressBar1.Value = 0;

            progressBar1.Maximum =operationCount ;

 

 

            backgroundWorker1 = new BackgroundWorker() { WorkerReportsProgress = true };

            backgroundWorker1.DoWork += new DoWorkEventHandler(this.backgroundWorker1_DoWork);

            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);

            backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);

 

            // on passe la variable en argument

            backgroundWorker1.RunWorkerAsync(operationCount);

        }

 

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)

        {

          

            for (int i = 0; i <= (int)e.Argument; i++)

            {

                Thread.Sleep(500); // pour la démo

                int n = i * 100 / ((int)e.Argument);

                backgroundWorker1.ReportProgress(n);

            }

        }

 

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)

        {

            label1.Text = string.Format("{0} %",e.ProgressPercentage.ToString());

            this.progressBar1.PerformStep();

 

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

        {

            MessageBox.Show("Fini !!");

        }

Repost 0
Published by Romagny13 - dans C
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:33

Récupérer les infos de base -SQL ServerCe – ce qui marche

 

 On peut facilement récupérer la liste des tables,des colonnes,pour les clés étrangères c’est un peu plus compliqué .  

 J’utilise les mêmes vues qu’avec Sql Server mais toutes ne sont pas disponibles .  

 http://msdn.microsoft.com/fr-fr/library/ms186778.aspx  

-- liste les tables

select TABLE_NAME,TABLE_TYPE from INFORMATION_SCHEMA.TABLES

 

-- informations de colonne

select TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,COLUMN_HASDEFAULT,

COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,AUTOINC_SEED

from INFORMATION_SCHEMA.COLUMNS

where TABLE_NAME='Client'

 

 

select CONSTRAINT_NAME,TABLE_NAME,COLUMN_NAME

from INFORMATION_SCHEMA.KEY_COLUMN_USAGE

 

select CONSTRAINT_TABLE_NAME,CONSTRAINT_NAME,

UNIQUE_CONSTRAINT_TABLE_NAME,UNIQUE_CONSTRAINT_NAME

from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS

 

-- CONSTRAINT_TYPE renvoie "FOREIGN KEY" ou "PRIMARY KEY"

select CONSTRAINT_NAME,TABLE_NAME,CONSTRAINT_TYPE

from INFORMATION_SCHEMA.TABLE_CONSTRAINTS

 

Clé étrangères  

select CONSTRAINT_TABLE_NAME as TABLE_FILLE,

CONSTRAINT_NAME as FK_NAME

,UNIQUE_CONSTRAINT_TABLE_NAME as TABLE_MERE,UNIQUE_CONSTRAINT_NAME as PK_NAME

from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS;

 

select COLUMN_NAME as CLE_ETRANGERE

from INFORMATION_SCHEMA.KEY_COLUMN_USAGE

Where CONSTRAINT_NAME ='FK_Client_Category' ;

 

 

select COLUMN_NAME as CLE_TABLE_MERE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE

Where CONSTRAINT_NAME ='PK_Category'

  

Et voilà on récupère toutes les informations de clé étrangères en une seule requête  

select a.CONSTRAINT_TABLE_NAME as TABLE_FILLE,

a.CONSTRAINT_NAME as FK_NAME

,a.UNIQUE_CONSTRAINT_TABLE_NAME as TABLE_MERE,a.UNIQUE_CONSTRAINT_NAME as PK_NAME,b.COLUMN_NAME as CLE_ETRANGERE,

b.CONSTRAINT_NAME,c.COLUMN_NAME as CLE_TABLE_MERE

from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as a

,INFORMATION_SCHEMA.KEY_COLUMN_USAGE as b,

INFORMATION_SCHEMA.KEY_COLUMN_USAGE as c

where b.CONSTRAINT_NAME=a.CONSTRAINT_NAME

and c.CONSTRAINT_NAME=a.UNIQUE_CONSTRAINT_NAME          

 

Autrement il est possible de passer par DbConnection .GetSchema()

 

(Très efficace pour récupérer les informations des bases Microsoft Acces , cela liste même les vues avec le corps .Beaucoup moins avec SqlServerCe qui reste assez compliqué à utiliser )

Repost 0
Published by Romagny13 - dans SQL
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:33

4-Les procédures stockées .

Il n’y pas de convention de nommage à proprement parler seulement quelques bonnes pratiques et « maladresses » à éviter

use [dbDemo]

go

CREATE PROCEDURE [dbo].[GetAllFromClient]

AS    

SELECT [Id],[Name],[Email]

FROM dbo.[Client]

go

 

CREATE PROCEDURE [dbo].[GetClient]

(

       @Id int

)

AS

SELECT [Id],[Name],[Email]

FROM dbo.[Client]

WHERE [Id]=@Id

go

 

CREATE PROCEDURE [dbo].[InsertClient](@Name char(100),@Email char(100),@CategoryId int)

AS

INSERT INTO [Client]([Name] ,[Email] ,[CategoryId] )

VALUES(@Name,@Email,@CategoryId)

SELECT SCOPE_IDENTITY();

go

 

CREATE PROCEDURE [dbo].[UpdateClient]

(     

       @Id int,     @Name nchar(100),   @Email nchar(100)

)

AS

UPDATE dbo.[Client] SET [Name]=@Name,[Email]=@Email

WHERE [Id]=@Id

go

 

CREATE PROCEDURE [dbo].[DeleteClient]

(

       @Id int

)

AS

DELETE FROM [dbo].[Client]

WHERE [Id]=@Id

go

 

 

5-DBNULL et nullables

Pour gérer les champs pour être « null » en base de données

- Du côté de de l’application on stockera les données lues dans des nullables(System.Nullables<T>) (rappel System.String n’a pas de nullable)

- DBNULL permettra au contraire de tester si une ligne lue avec le datareader est « null »

Exemple : Dans la classe Client.cs

public Nullable<int> Age { get; set; }

 

Dans la classe d’accès aux données

if(reader["Age"] != DBNull.Value)

    client.Age = Convert.ToInt32(reader["Age"]);

 

- Il est également possible  d’affecter la valeur de défaut du type et ne pas avoir besoin des nullables

if (reader["Email"] == DBNull.Value)

                    client.Email = default(string);

                   else

                     client.Email=reader["Email"].ToString();

// ou

client.Email = reader["Email"] == DBNull.Value ? default(string) : reader["Email"].ToString();

 

6-Construction de l’application – Couches

Il y a :

- La couche d’accès aux données(DAL) avec les classes (exemple ClientDAO) permettant de se connecter à une source de données/base

- La couche des objets métiers (business objects contenant les classes comme Client.cs) qui servent à stocker temporairement les données que l’on récupère de la base

- La couche interface utilisateur (Gui : windows form,pages web,…) qui permet d’afficher les informations (consultation)  et la mise à jour

 

A cela on peut ajouter une couche « Manager »(BLL), une sorte de chef d’orchestre entre l’ui ,la couche métier et la couche d’accès aux données . 

 

 

    7-Binding

Avec Windows forms il est possible d’utiliser BindingList<T> et INotifyPropertyChanged

Il est possible de convertir une liste générique List<T> en BindingList<T> ainsi

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

BindingList<Client> bindingClients = new BindingList<Client>(clients);

 

La bindingList permet de notifier les changements au niveau de la collection(ajout,suppression d’un élément)et INotifyPropertyChanged permet de notifier les changements au niveau d’un élément(exemple : on modifie l’email d’un client) .L’interface utilisateur se mettra à jour « automatiquement »

public class Client :INotifyPropertyChanged

    {

        // ... code enlevé pour la clarté de l'exemple

      

        private string _email;

      

        public string Email { get { return _email; }

            set

            {

                _email = value;

                this.OnPropertyChanged("Email");

            }

        }

     

        public event PropertyChangedEventHandler PropertyChanged;

 

        public void OnPropertyChanged(string propertyName)

        {

            if (this.PropertyChanged != null)

            {

                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

 

     Avec WPF on préfèrera utiliser ObservableCollection donc j’ai parlé dans un article précédent.

 

    8-Vue Liste/détail :

utile pour afficher une liste dans une grille(comme le datagridView) et le détail(en vue de modifier par exemple) .Il est possible également de permettre l’édition dans le datagridView (readonly) .

On met à jour après vérification que la ligne respecte les contraintes (exemple une valeur n’acceptant pas les valeurs nulles, un email devant respecter un format avec une regex,un champ age n’acceptant que des chiffres,etc.)

Exemple je vérifie la cellule venant d’être modifiée.Si elle est vide j’affiche un message d’erreur,si tout est bon je mets à jour la base de données . J’affiche également à l’utilisateur la valeur de la cellule avant son édition (dataGridView1.CurrentCell.Value)

                private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)

        {

            if (string.IsNullOrEmpty(e.FormattedValue.ToString().Trim()))

            {

 

                //afficher l'erreur au niveau de la ligne

                // dataGridView1.Rows[e.RowIndex].ErrorText ="message d'erreur";

 

                // ou au niveau de la cellule courante

                dataGridView1.CurrentCell.ErrorText = string.Format("Cette cellule a été modifiée .Une Valeur est nécessaire.La modification n'a pas été enregistrée en base de données .Valeur d'origine : {0} ",dataGridView1.CurrentCell.Value);

 

                //e.Cancel = true;

            }

            else

            {

                if (loading == false)

                {

                    // on met à jour la base

                    Client client = (Client)dataGridView1.SelectedRows[0].DataBoundItem;

                    clientDAO.UpdateClient(client);

                }

            }

 

Pour aller plus loin :

On pourra parler des générateurs de code,d’entreprise Library,ADO Entity,MVVM et tellement de pistes .

Je parlerai aussi de DbProvider

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:32

3- La commande(SqlCommand)

La commande a besoin d’une connexion, d’une requête/procédure stockée. Elle peut également avoir besoin de paramètres. C’est elle qui va permettre de retourner des lignes avec un Datareader (requète select), effectuer une mise à jour (requête insert,update,delete,etc.) avec executeNonQuery .ExecuteScalar permettra de retourner un résultat comme la clé du dernier ajouté dans une table .

Il est important de libérer rapidement  les ressources dans une application accédant aux données , gérer les accès concurrentiels. C’est pour cela qu’on utilise les singletons, que l’on ferme rapidement la connexion et que l’on détruit les objets accédant à la base(en utilisant using)

- récupérer une liste

               public List<Client> GetClients()          

        {

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

            SqlConnection connection = Sql.Instance.GetConnection();

 

             using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "GetAllFromClient";

                using (SqlDataReader reader = command.ExecuteReader())

                {

                    while (reader.Read())

                    {

                        Client client = new Client();

                        client.Id = reader["Id"] == DBNull.Value ? default(int) : int.Parse(reader["Id"].ToString());

                        client.Name = reader["Name"] == DBNull.Value ? default(string) : reader["Name"].ToString();

                        client.Email = reader["Email"] == DBNull.Value ? default(string) : reader["Email"].ToString();

                        client.CategoryId = reader["CategoryId"] == DBNull.Value ? default(int) : int.Parse(reader["CategoryId"].ToString());

 

                        clients.Add(client);

                    }

                }

            }

 

            connection.Close();

 

            return clients;

        }

- ajout, on récupère la clé du dernier ajouté avec SCOPE_IDENTITY() (voir plus loin les procédures stockées) (article intéressant

              public int AddClient(Client client)

        {

            int result = 0;

            SqlConnection connection = Sql.Instance.GetConnection();

 

            using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "InsertClient";

                command.Parameters.Add(new SqlParameter("@Name", client.Name));

                command.Parameters.Add(new SqlParameter("@Email", client.Email));

                command.Parameters.Add(new SqlParameter("@CategoryId", client.CategoryId));

 

                result = Convert.ToInt32(command.ExecuteScalar());

            }

            connection.Close();

 

            return result;

        }

- Obtenir une ligne/un élément par sa clé primaire

              public Client GetClient(int id)

        {

            Client client = new Client();

            SqlConnection connection = Sql.Instance.GetConnection();

 

            using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "GetClient";

                command.Parameters.Add(new SqlParameter("@Id", id));

 

                using (SqlDataReader reader = command.ExecuteReader())

                {

                    while (reader.Read())

                    {

                        client.Id = reader["Id"] == DBNull.Value ? default(int) : int.Parse(reader["Id"].ToString());

                        client.Name = reader["Name"] == DBNull.Value ? default(string) : reader["Name"].ToString();

                        client.Email = reader["Email"] == DBNull.Value ? default(string) : reader["Email"].ToString();

                        client.CategoryId = reader["CategoryId"] == DBNull.Value ? default(int) : int.Parse(reader["CategoryId"].ToString());

                    }

                }

            }

            connection.Close();

 

            return client;

        }

 

- Update

               public int UpdateClient(Client client)

        {

            int result = 0;

            SqlConnection connection = Sql.Instance.GetConnection();

 

            using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "UpdateClient";

                command.Parameters.Add(new SqlParameter("@Id", client.Id));

                command.Parameters.Add(new SqlParameter("@Name", client.Name));

                command.Parameters.Add(new SqlParameter("@Email", client.Email));

                command.Parameters.Add(new SqlParameter("@CategoryId", client.CategoryId));

 

                result = command.ExecuteNonQuery();

            }

            connection.Close();

 

            return result;

        }

 

- Delete

              public int RemoveClient(Client client)

        {

            int result = 0;

            SqlConnection connection = Sql.Instance.GetConnection();

 

            using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.StoredProcedure;

                command.CommandText = "DeleteClient";

                command.Parameters.Add(new SqlParameter("@Id", client.Id));

 

                result = command.ExecuteNonQuery();

            }

            connection.Close();

 

            return result;

        }

 

- Rechercher : Il peut être utile aussi d’avoir une fonction de recherche .Un exemple tout simple sur le nom de client .Cela retourne une liste dont le nom ressemble à la saisie

 

               public List<Client> SearchClient(string match)

        {

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

            SqlConnection connection = Sql.Instance.GetConnection();

 

            using (SqlCommand command = connection.CreateCommand())

            {

                command.CommandType = CommandType.Text;

                command.CommandText = "SELECT * FROM [Client] WHERE Name LIKE '%' + RTRIM(@Name) + '%'";

                command.Parameters.Add(new SqlParameter("@Name", match));

                using (SqlDataReader reader = command.ExecuteReader())

                {

                    while (reader.Read())

                    {

                        Client client = new Client();

                        client.Id = reader["Id"] == DBNull.Value ? default(int) : int.Parse(reader["Id"].ToString());

                        client.Name = reader["Name"] == DBNull.Value ? default(string) : reader["Name"].ToString();

                        client.Email = reader["Email"] == DBNull.Value ? default(string) : reader["Email"].ToString();

                        client.CategoryId = reader["CategoryId"] == DBNull.Value ? default(int) : int.Parse(reader["CategoryId"].ToString());

 

                        clients.Add(client);

                    }

                }

            }

            return clients;

       

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article
2 février 2014 7 02 /02 /février /2014 01:32

1-La chaine de connexion 

Site connectionString http://www.connectionstrings.com/

Il est préférable de la définir dans le fichier de configuration de l’application(app.config) dans la section <connectionStrings></connectionStrings>

Exemple chaine de connexion pour un fichier *.mdf

<connectionStrings>

    < add name="dbConnectionString"

         connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\dbDemo.mdf;Integrated Security=True"

         providerName="System.Data.SqlClient" />

  </connectionStrings>

 

Exemple avec base de données SQL Server Express 2012

<add name="dbConnectionString"

         connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=dbDemo;Integrated Security=SSPI;"

         providerName="System.Data.SqlClient" />

 

Il est possible de crypter la chaine de connexion  si besoin pour plus de sécurité

Exemple

private  void Encrypt()

        {

            // chemin complet vers l'*.EXE

            Configuration configuration = ConfigurationManager.OpenExeConfiguration(@"C:\Users\romagny\Documents\Visual Studio 2013\Projects\DataTraining\DataTraining\bin\Debug\DataTraining.exe");// (ConfigurationUserLevel.None);

            ConfigurationSection connectionStrings = configuration.GetSection("connectionStrings");

            if (connectionStrings != null)

                if (!connectionStrings.SectionInformation.IsProtected)

                {

                    configuration.ConnectionStrings.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");

                    // connectionStrings.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");

                    configuration.Save(ConfigurationSaveMode.Full, true);

                }

        }

        private string Decrypt()

        {

           // Configuration config = ConfigurationManager.OpenExeConfiguration(@"C:\Users\romagny\Documents\Visual Studio 2013\Projects\DataTraining\DataTraining\bin\Debug\DataTraining.exe");

            // ou

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            return config.ConnectionStrings.ConnectionStrings[1].ConnectionString;

        }

 

2-La connexion(SqlConnection)

On utilise un singleton.Le Namespace  System.Data.SqlClient .

Lock http://msdn.microsoft.com/fr-fr/library/c5kehkcz(v=vs.90).aspx

 

public class Sql

    {

        private static Sql _instance;

        private SqlConnection connection;

        private static object locker = new object();

        public ConnectionStringSettings ConnectionStringSettings { get; set; }

 

        private Sql() { }

 

        public static Sql Instance

        {

            get

            {

                lock (locker) // verrouille le bloc de code

                {

                    if (_instance == null)

                        _instance = new Sql();

                }

 

                return _instance;

            }

        }

        public SqlConnection GetConnection()

        {        

            if (connection == null)

            {

                ConnectionStringSettings = ConfigurationManager.ConnectionStrings["dbConnectionString"]; // ou ConfigurationManager.ConnectionStrings[1] l'index commence à 1

                connection = new SqlConnection(ConnectionStringSettings.ConnectionString);

            }               

           

            if (connection.State == ConnectionState.Closed)

                connection.Open();

           

            return connection;

        }     

        public void CloseConnection()

        {

            if (this.connection != null)

            {

                if (this.connection.State != ConnectionState.Closed)

                {

                    this.connection.Close();

                }

            }

        }

    }

 

Repost 0
Published by Romagny13 - dans ADO.NET
commenter cet article