Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Utilisation de la réplication SQL dans le code .NET d'une application mobile - Implémentation & Conseils : PARTIE 1/3 (classe SqlCeReplication & première synchro)

J’ai décidé de laisser de coté mes articles “théoriques” sur la réplication de fusion avec SQL Server Compact, pour laisser un peu plus de place à la pratique.

Voyons donc maintenant comment tout cela se met en action dans le code .NET d’une application mobile !

Dans le .NET Compact Framework, c’est la classe SqlCeReplication, de l’espace de nom System.Data.SqlServerCe qui permet de prendre en charge la réplication SQL.

Dans cette première partie, nous allons voir comment s’utilisent les propriétés et les méthodes de la classe SqlCeReplication. Nous allons étudier, étape par étape, la construction d’un code C# simple pour effectuer une synchronisation de données dans une application Windows Mobile.

 

Utilisation de la classe SqlCeReplication :

Partons d’une simple application, qui ne comporte qu’un seul écran sur lequel nous avons placé un bouton “SYNCHRO” qui va nous permettre de lancer la synchronisation :

imagePour pouvoir utiliser la réplication SQL et plus particulièrement la classe SqlCeReplication, il est d’abord nécessaire de rajouter une référence à l’assembly System.Data.SqlServerCe :

image Dans le code-behind de l’unique “form”, nous allons commencer par rajouter un “using” à l’espace de nom “System.Data.SqlServerCe” :

using System.Data.SqlServerCe;

Ensuite, nous allons définir une constante qui correspond au nom de la base mobile que nous allons créer par réplication :

private const string _dbName = "DBmob.sdf";

Dans le code de l’évènement “Click” associé au bouton synchro, nous allons créer un objet “repl” de type SqlCeReplication et l’instancier à l’intérieur d’une clause “try-catch-finally”.

Le code C# ci-dessous correspond au squelette de départ de notre exemple :

using System;
using System.Data.SqlServerCe;
using System.Windows.Forms;

namespace TestReplication1
{
    public partial class Form1 : Form
    {
        private const string _dbName = "DBmob.sdf";

        public Form1()
        {
            InitializeComponent();
        }

        private void btnSynchro_Click(object sender, EventArgs e)
        {
            SqlCeReplication repl = null;
            try
            {
                repl = new SqlCeReplication();
            }
            catch (SqlCeException ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (repl != null)
                    repl.Dispose();
            }

        }
    }
}

Remarque :

N’oubliez pas d’attraper les éventuelles SqlCeException dans la clause “catch” et de détruire l’objet “repl” dans la clause “finally”.

 

Définition des propriétés :

La classe SqlCeReplication possède de nombreuses propriétés qu’il est important de bien définir selon l’environnement utilisé (web synchro, Publisher, Distributor, etc…).

La définition de l’ensemble de ces propriétés n’est pas obligatoire et dépend entre autre du type de sécurité utilisée et de la configuration du distributor. Certaines propriétés, quant à elles, doivent obligatoirement être définies pour pouvoir effectuer une synchronisation, c’est le cas par exemple des propriétés Subscriber, Publication, InternetUrl, etc.…

Description de certaines propriétés :

  • InternetUrl: URL de l’agent de réplication exposé sur IIS.
  • InternetLogin: Login du compte utilisateur utilisé pour la connexion au répertoire virtuel IIS.
  • InternetPassword: Mot de passe du compte utilisateur utilisé pour la connexion au répertoire virtuel IIS.
  • Publisher: Nom de l’instance SQL sur laquelle tourne la base publisher.
  • PublisherSecurityMode: Type de sécurité utilisée pour la connexion à la base publisher (NT ou DB selon si la connexion à la base publisher s’effectue via un compte Windows ou un compte SQL Server).
  • PublisherLogin: Login du compte utilisé pour la connexion au publisher (dans le cas d’un type de sécurité DB).
  • PublisherPassword: Mot de passe du compte utilisé pour la connexion au publisher (dans le cas d’un type de sécurité DB).
  • PublisherDatabase: Base de données publisher à répliquer.
  • Publication: Nom de la publication à utiliser.
  • Distributor: Nom de l’instance SQL sur laquelle tourne la base de distribution (inutile de préciser dans le cas où le publisher et le distributor sont sur la même machine).
  • DistributorLogin: Login du compte utilisé pour la connexion à la base de distribution (inutile de préciser dans le cas où le publisher et le distributor sont sur la même machine).
  • DistributorPassword: Mot de passe du compte utilisé pour la connexion à la base de distribution (inutile de préciser dans le cas où le publisher et le distributor sont sur la même machine).
  • SubscriberConnectionString: Chaine de connexion à la base de données mobile répliquée.
  • Subscriber: Nom de l’abonnement.
  • HostName: valeur récupérée pour la fonction de filtrage HOST_NAME().
  • CompressionLevel: Cette propriété permet de personnaliser la compression de données. Elle peut prendre une valeur comprise entre 0 et 6. La valeur 0 désactive toute compression.  La valeur par défaut est 1.

Conseil :

En spécifiant une valeur faible pour la propriété CompressionLevel, les données transmises ne seront pas fortement compressées, ce qui rallonge donc la durée de transmission. Par contre, plus la valeur est élevée, plus le temps des traitements de compression sera long sur le serveur, mais la durée de transfert sera d’autant plus courte. Il est donc question de trouver un juste milieu par rapport aux besoins. Par exemple, si le coût des données transmises est important pour le projet (forfait opérateur GPRS), il sera peut-être nécessaire  d’augmenter la compression de données.

Astuce :

En ce qui concerne la chaine de connexion de l’abonnement SubscriberConnectionString, il faut savoir qu’il est possible de rajouter la clause “Max Database Size=X” afin de repousser la limite de taille définie par défaut pour les bases mobiles répliquées. En effet, par défaut la limite de taille de la base répliquée est fixée à 128Mo. Par exemple, en précisant “Max Database Size = 1000” dans la chaine de connexion, la base répliquée pourra atteindre une taille de 1Go. (La limite maximale réelle étant de 4 Go pour SQL Server Compact 3.5).

Procédure :

Juste après l’instanciation de l’objet “repl”, nous allons définir l’ensemble de ses propriétés de telle manière à pouvoir utiliser correctement une publication nommée “Pub” qui a été construite et configurée sur une base de données “BASE”.

repl = new SqlCeReplication();
repl.InternetUrl = "http://10.10.10.10/webSync/sqlcesa35.dll";
repl.InternetLogin = "login";
repl.InternetPassword = "password";
repl.Publisher = @"INSTANCE_SQL";
repl.PublisherDatabase = "BASE";
repl.PublisherSecurityMode = SecurityType.NTAuthentication;
repl.Publication = "Pub";
repl.Subscriber = "PDA1";
repl.HostName = "PDA1";
repl.SubscriberConnectionString = @"Data Source=" + _dbName
                      + ";Max Database Size=1000;Default Lock Escalation =100;";

Dans l’exemple ci-dessus, nous avons donc précisé les paramètres de connexion au serveur ISS (dont l’URL de la DLL de réplication), ainsi que les paramètres du serveur de publication.

Le type de sécurité étant “NT Authentication” dans cet exemple, nous n’avons pas besoin de renseigner les propriétés PublisherLogin et PublisherPassword qui sont uniquement utilisées dans le cadre d’une authentification à l’aide d’un compte SQL Server.

Les propriétés du distributor n’ont pas non plus été précisées puisque nous considérons que le distributor et le publisher sont sur le même serveur.

La propriété HostName a été définie à “PDA1”. Pour rappel, cette valeur sera utilisée pour initialiser le système de filtres (Cf. article ici).

Astuce :

Les SDK et frameworks utilisés lors du développement d’une application mobile permettent en général de récupérer très facilement le numéro de série de l’appareil. Il peut s’avérer intéressant de créer une table “TERMINAUX”, sur la base de données serveur, qui contiendrait l’ensemble des références des terminaux portables, et qui serait utilisée pour initialiser le système de filtres.

Par exemple, en répliquant le terminal expose son numéro de série dans le “HostName”. Dès lors, le système de filtres s’applique par rapport à ce numéro de série stocké dans une table “TERMINAUX” de la base de données. Cette ligne spécifique de la table “TERMINAUX” permettra d’effectuer les jointures nécessaires avec les autres tables (utilisateurs, clients, périmètre géographique…), pour déterminer l’ensemble des données du référentiel qui doivent descendre sur ce terminal spécifique.

 

Méthodes et synchronisation des données :

La classe SqlCeReplication présente plusieurs méthodes importantes pour la synchronisation de données.

Description des méthodes :

  • AddSubscription : Cette méthode permet de créer l’abonnement. Cette méthode est indispensable dans le sens où l’abonnement doit obligatoirement être créé avant de pouvoir lancer la synchronisation des données. Il est possible de spécifier l’option “CreateDatabase” pour générer automatiquement la base de données mobile si elle n’existe pas.
  • DropSubscription: Cette méthode supprime l’abonnement lié à la base mobile.
  • SaveProperties: Cette méthode permet de stocker l’ensemble des propriétés définies par la classe SqlCeReplication à l’intérieur d’une table système de la base répliquée.
  • LoadProperties: Cette méthode peut être appelée suite à un “SaveProperties” pour retrouver l’ensemble des propriétés de la réplication mémorisées sur l’abonné.
  • Synchronize: C’est la méthode qui permet de lancer la synchronisation de données en mode synchrone.
  • BeginSynchronize: C’est la méthode qui permet de lancer la synchronisation de données en mode asynchrone.

Remarque & Conseils :

La méthode AddSubscription est très importante dans le sens où elle doit obligatoirement être appelée pour créer l’abonnement avant de pouvoir effectuer une synchronisation. Si la base de données mobile existe déjà, il est question de préciser l’option “ExistingDatabase”. Sinon, l’option “CreateDatabase” permettra de générer automatiquement la base de données par réplication, au chemin spécifié par la chaine de connexion SubscriberConnectionString.

La méthode LoadProperties est utile par exemple dans le cas où une base mobile serait générée par réplication en dehors de l’application mobile, et copiée sur l’appareil. Dans ce cas, il suffit de faire appel à LoadProperties, dans le code de l’application mobile, pour rappeler facilement l’ensemble des propriétés définies. Suite à un LoadProperties, la méthode AddSubscription n’a plus besoin d’être appelée. Seules certaines propriétés comme les mots de passe, ou le HOST_NAME ne sont pas sauvegardées et doivent de nouveau être précisées juste avant de lancer la synchronisation.

Procédure :

Maintenant que nous avons défini l’ensemble des propriétés nécessaires, nous allons rajouter l’abonnement sur la base en spécifiant que la base mobile doit être générée entièrement par réplication.

Pour ce faire, nous allons faire appel à la méthode AddSubscription et préciser l’option CreateDatabase pour créer entièrement la base par réplication :

repl.AddSubscription(AddOption.CreateDatabase);

La création de la base mobile et l’ajout de l’abonnement ne sont valables uniquement lors de la première synchro. En effet, pour les synchronisations suivantes, la base sera déjà créée et l’abonnement sera déjà présent sur la base. C’est pourquoi, il est intelligent de tester au préalablement l’existence de la base de données pour effectuer l’ajout de l’abonnement avec l’option CreateDatabase :

if (!System.IO.File.Exists(_dbName))
                    repl.AddSubscription(AddOption.CreateDatabase);

Suite à l’ajout de l’abonnement, nous pouvons enfin appeler la méthode Synchronize qui permet de lancer la synchronisation. Voici à quoi ressemble à présent l’ensemble du code de la “form” :

using System;
using System.Data.SqlServerCe;
using System.Windows.Forms;

namespace TestReplication1
{
    public partial class Form1 : Form
    {
        private const string _dbName = "DBmob.sdf";

        public Form1()
        {
            InitializeComponent();
        }

        private void btnSynchro_Click(object sender, EventArgs e)
        {
            SqlCeReplication repl = null;
            try
            {
                repl = new SqlCeReplication();
                repl.InternetUrl = "http://10.10.10.10/webSync/sqlcesa35.dll";
                repl.InternetLogin = "login";
                repl.InternetPassword = "password";
                repl.Publisher = @"INSTANCE_SQL";
                repl.PublisherDatabase = "BASE";
                repl.PublisherSecurityMode = SecurityType.NTAuthentication;
                repl.Publication = "Pub";
                repl.Subscriber = "PDA1";
                repl.HostName = "PDA1";
                repl.SubscriberConnectionString = @"Data Source=" + _dbName
                      + ";Max Database Size=1000;Default Lock Escalation =100;";

                if (!System.IO.File.Exists(_dbName))
                    repl.AddSubscription(AddOption.CreateDatabase);

                repl.Synchronize();
            }
            catch (SqlCeException ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (repl != null)
                    repl.Dispose();
            }
        }
    }
}

Il s’agit bien entendu d’un exemple simple qui permet de comprendre au mieux comment faire appel à la réplication SQL dans une application mobile.

Le code de la réplication doit être modulé selon les projets. Il n’est surtout pas question de reprendre le code C# tel qu’il est présenté ci-dessus, mais plutôt de l’adapter à votre architecture et en fonction de vos besoins.

A suivre…

Pi-R.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

vendredi 8 octobre 2010 16:25 by marric01

# re: Utilisation de la réplication SQL dans le code .NET d'une application mobile - Implémentation & Conseils : PARTIE 1/3 (classe SqlCeReplication & première synchro)

Bonjour Pierre !

Super article. Je me demandais si c'étais possible de faire la même chose avec SQL Server Express 2008. Je veux développer un appli en C# avec base de données SQL. L'appli est sur un ordinateur portable et l'usager n'est pas toujours connecté à internet. Est-ce que je devrais utiliser SQL Compact ou SQL Server Express sur le poste client ?

J'aimerais pouvoir faire une synchro dans les deux sens.

Richard

Merci et bonne journée !

vendredi 8 octobre 2010 17:53 by Pi-R

# re: Utilisation de la réplication SQL dans le code .NET d'une application mobile - Implémentation & Conseils : PARTIE 1/3 (classe SqlCeReplication & première synchro)

Salut Marric,

Merci beaucoup pour ton commentaire.

Pour répondre à ta question, les bases de type SQL Server Express ne peuvent être que "abonnées" de la réplication. Dans tous les cas, il te faudra un serveur SQL Server (non express) pour configurer tes publications.

Si tu développes un client lourd Windows, tu peux facilement utiliser une base SQL Server Compact sur le poste de travail pour utiliser la réplication de fusion comme je la présente dans mes articles.

SQL Server Compact ne nécessite aucune installation particulière sur le poste client.

Lors de ton déploiement, il y aura juste l'install de ton application à faire.

La base SQL Server Compact pourra être considérée comme un simple fichier de stockage de données ".sdf" qui pourra être soit généré automatiquement sur le poste par réplication ou alors embarqué dans ton setup, et qui pourra se baser sur une publication serveur pour synchroniser des données.

J'espère répondre correctement à tes questions.

N'hésites surtout pas à me poser d'autres questions si tu as besoin d'aide.

Pi-R.

vendredi 8 octobre 2010 19:15 by marric01

# re: Utilisation de la réplication SQL dans le code .NET d'une application mobile - Implémentation & Conseils : PARTIE 1/3 (classe SqlCeReplication & première synchro)

Re-Salut Pierre

En fait, j'ai un SQL Server 2008 Entreprise qui hégergera la base de donnée "master". Elle servira également de base de données pour afficher des éléments sur un site web. Le serveur est un Windows 2008 Entreprise.

Donc, si je comprend bien, il serait plus simple d'utiliser un SQL compact pour mon application client lourd et de permettre au client de synchroniser via internet(bi-directionnellement) quand il est connecté à internet. Donc, le client utilise un laptop pour ajouter de nouvelles données et en modifier ... quand il a une connexion internet de disponible ... il envoit les données aux serveur et recoit les nouvelles données du serveur.

Mon application est déjà existante (j'avais utilisé microsoft access 2000 avec Replication Manager 4.0) ... Ça fonctionne bien mais il n'y a plus rien de supporté et il serait temps de changer pour de la technologie plus robuste et fiable ;-). J'ai environ 30 tables et la taille est relativement petite (150mb pour 6 ans de données). Il s'agit d'un logiciel de gestion de ligue de hockey.

Merci encore !

Richard

P.S. Vos autres articles sont également très interessants !

lundi 11 octobre 2010 08:01 by Pi-R

# re: Utilisation de la réplication SQL dans le code .NET d'une application mobile - Implémentation & Conseils : PARTIE 1/3 (classe SqlCeReplication & première synchro)

Salut Richard !

Pas de problème pour ton serveur.

Pour tes postes clients, voici le scénario que je te propose (c'est une possibilité parmi d'autres):

1) Tu ne déploies que ton applicatif sur le poste client.

2) A la première connexion (première utilisation de l'utilisateur), le client génère et crée sa base de données .sdf (compact) par réplication SQL. Il n'y a 150Mo max, ça devrait aller vite.

Il serait même intéressant de rajouter un système de filtres à ton système de réplication (voir un de mes articles). De cette manière, dans la base de données du client il n'y aura que les données pour lui, et la volumétrie sera donc réduite.

3) Ton application peut alors fonctionner avec la base de données créée. Elle peut modifiée des données et les synchroniser en bidirectionnel.

Merci pour tes encouragements.

Encore une fois, n'hésites pas si tu as d'autres questions.

Pi-R.

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01