Procédure pas à pas : création d'un générateur de données personnalisé pour une contrainte de validation
Mise à jour : novembre 2007
Vous pouvez utiliser des générateurs de données standard pour remplir des colonnes de données dans Visual Studio Team System Database Edition. Si une contrainte de validation est définie sur la colonne que vous voulez remplir, les données avec lesquelles vous remplissez la colonne doivent répondre à la contrainte de validation. Les générateurs de données standard peuvent générer des données qui répondent à de nombreuses contraintes de validation. Par exemple, si une contrainte de validation nécessite qu'une date figure dans une certaine plage, vous pouvez utiliser le générateur DateTime standard et définir les propriétés Min et Max pour satisfaire à cette contrainte.
Toutefois, les générateurs de données standard ne peuvent pas répondre à toutes les contraintes de validation. Par exemple, si une contrainte de validation nécessite qu'une date figure dans l'une de deux plages distinctes, vous ne pouvez pas utiliser le générateur DateTime standard. Dans cette procédure pas à pas, vous créez un générateur de données personnalisé qui peut satisfaire à une telle contrainte. Le générateur accepte deux plages comme entrée, puis génère une date aléatoire qui figure dans l'une de ces deux plages.
Remarque : |
---|
Vous pouvez suivre une autre approche pour créer un générateur de données personnalisé et atteindre le même objectif en utilisant l'extensibilité d'agrégation. Pour plus d'informations, consultez Procédure pas à pas : création d'un générateur de données personnalisé qui regroupe des générateurs standard. |
Dans cette procédure pas à pas, vous exécutez les tâches suivantes :
Créer une classe qui hérite de Generator.
Créer des propriétés d'entrée afin que l'utilisateur puisse indiquer les deux plages de dates.
Créer une propriété de sortie à utiliser comme sortie de générateur.
Substituer la méthode OnInitialize pour donner une valeur de départ aux objets Random et rendre votre générateur déterministe.
Substituer la méthode OnGenerateNextValues pour générer les données.
Signer le générateur avec un nom fort.
Composants requis
Pour exécuter cette procédure pas à pas, vous devez disposer des éléments suivants :
- Database Edition
Création de la classe du générateur de données personnalisé
Pour créer la classe du générateur de données personnalisé
Dans Visual Studio, créez un projet Bibliothèque de classes dans le langage de votre choix, puis nommez-le GeneratorDateRanges.
Dans le menu Projet, cliquez sur Ajouter une référence.
La boîte de dialogue Ajouter une référence s'affiche.
Cliquez sur l'onglet .NET. Dans la liste Nom du composant, cliquez sur Microsoft.VisualStudio.TeamSystem.Data, puis sur OK.
(Facultatif, Visual Basic uniquement) Dans l'Explorateur de solutions, cliquez sur Afficher tous les fichiers, puis développez le nœud Références pour vérifier la nouvelle référence.
En haut de la fenêtre Code, avant la déclaration de classe, ajoutez la ligne de code suivante :
Imports Microsoft.VisualStudio.TeamSystem.Data.DataGenerator Imports System.Data.SqlTypes
using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator; using System.Data.SqlTypes;
Renommez la classe Class1 en GeneratorDateRanges, puis indiquez qu'elle hérite de Generator.
Attention : Par défaut, le nom que vous donnez à votre classe est le nom qui apparaît dans la liste affichée dans la colonne Générateur de la fenêtre Détails de la colonne. Vous devez spécifier un nom qui ne crée pas de conflit avec le nom d'un générateur standard ou d'un autre générateur personnalisé.
Public Class GeneratorDateRanges Inherits Generator End Class
public class GeneratorDateRanges: Generator { }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Ajout des propriétés d'entrée
Ce générateur de données personnalisé accepte deux plages de dates comme entrée. Pour spécifier chaque plage, l'utilisateur indique les dates minimales et maximales pour chacune d'elles. Par conséquent, vous devez créer quatre propriétés d'entrée au total : deux dates minimales et deux dates maximales.
Pour ajouter les propriétés d'entrée
Créez quatre variables membres pour contenir les dates minimales et maximales des deux plages de dates.
Dim range1MinValue As SqlDateTime Dim range1MaxValue As SqlDateTime Dim range2MinValue As SqlDateTime Dim range2MaxValue As SqlDateTime
SqlDateTime range1MinValue; SqlDateTime range1MaxValue; SqlDateTime range2MinValue; SqlDateTime range2MaxValue;
Créez quatre propriétés pour définir les dates minimales et maximales des deux plages de dates. Les propriétés doivent comporter l'InputAttribute pour les identifier comme propriétés d'entrée.
<Input(TypeConverter:= GetType(SqlDateTimeConverter))> _ Public Property Range1Min() As SqlDateTime Set(ByVal value As SqlDateTime) range1MinValue = value End Set Get Return range1MinValue End Get End Property <Input(TypeConverter:= GetType(SqlDateTimeConverter))> _ Public Property Range1Max() As SqlDateTime Set(ByVal value As SqlDateTime) range1MaxValue = value End Set Get Return range1MaxValue End Get End Property <Input(TypeConverter:= GetType(SqlDateTimeConverter))> _ Public Property Range2Min() As SqlDateTime Set(ByVal value As SqlDateTime) range2MinValue = value End Set Get Return range2MinValue End Get End Property <Input(TypeConverter:= GetType(SqlDateTimeConverter))> _ Public Property Range2Max() As SqlDateTime Set(ByVal value As SqlDateTime) range2MaxValue = value End Set Get Return range2MaxValue End Get End Property
[Input(TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range1Min { set {range1MinValue = value;} get {return range1MinValue;} } [Input(TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range1Max { set {range1MaxValue = value;} get {return range1MaxValue;} } [Input(TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range2Min { set {range2MinValue = value;} get {return range2MinValue;} } [Input(TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range2Max { set {range2MaxValue = value;} get {return range2MaxValue;} }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Ajout de la propriété de sortie
Ce générateur de données personnalisé retourne une date aléatoire en tant que sortie. Par conséquent, vous devez créer une propriété de sortie.
Pour ajouter la propriété de sortie
Créez une variable membre pour contenir la date aléatoire qui représente la sortie.
Dim randomDateValue As SqlDateTime
SqlDateTime randomDateValue;
Créez une propriété pour retourner la date aléatoire en tant que sortie. La propriété doit comporter l'OutputAttribute pour l'identifier comme propriété de sortie.
<Output()> _ Public ReadOnly Property RandomDate() As SqlDateTime Get Return randomDateValue End Get End Property
[Output] public SqlDateTime RandomDate { get {return randomDateValue;} }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Substitution de la méthode OnInitialize
Lorsque vous générez des données aléatoires, elles peuvent être déterministes ou non déterministes. Les données déterministes répètent les mêmes données chaque fois que vous les générez avec la même valeur de départ. Tous les générateurs de données ont une propriété Seed que l'utilisateur peut définir. Vous pouvez substituer la méthode OnInitialize pour donner une valeur de départ aux objets Random et rendre votre générateur déterministe.
Pour substituer la méthode OnInitialize
Créez deux variables membres pour générer des nombres aléatoires, comme indiqué dans l'exemple suivant. Une variable génère une date aléatoire. L'autre variable effectue un choix aléatoire entre les deux plages de dates possibles.
Dim random As Random Dim randomRange As Random
Random random; Random randomRange;
Substituez la méthode OnInitialize.
Protected Overrides Sub OnInitialize(ByVal initInfo As GeneratorInit) random = New Random(Me.Seed) 'deterministic randomRange = New Random(Me.Seed) 'deterministic 'random = New Random() 'non-deterministic 'randomRange = New Random() 'non-deterministic MyBase.OnInitialize(initInfo) End Sub
protected override void OnInitialize(GeneratorInit initInfo) { random = new Random(this.Seed); //deterministic randomRange = new Random(this.Seed); //deterministic //random = new Random(); //non-deterministic //randomRange = new Random(); //non-deterministic base.OnInitialize(initInfo); }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Substitution de la méthode OnGenerateNextValues
Database Edition appelle la méthode OnGenerateNextValues du générateur pour créer les données nécessaires. Vous devez substituer cette méthode pour fournir la logique qui génère la date aléatoire pour la propriété de sortie.
Pour substituer la méthode OnGenerateNextValues
Substituez la méthode OnGenerateNextValues, comme illustré dans l'exemple suivant.
Protected Overrides Sub OnGenerateNextValues() Dim min As SqlDateTime Dim max As SqlDateTime 'Generate a random date from either range 1 or range 2. 'Randomly select either range 1 or range 2 by randomly 'generating an odd or an even random number. '------------------------------------------------------------ If randomRange.Next() Mod 2 = 0 Then 'check for odd or even min = range1MinValue max = range1MaxValue Else min = range2MinValue max = range2MaxValue End If 'The formula for creating a random number in a specific range is: 'start of range + (size of range * random number between 0 and 1) 'size of range Dim range As TimeSpan = max.Value - min.Value '(size of range * random number between 0 and 1) Dim randomNumber As TimeSpan = New TimeSpan(CLng(range.Ticks * random.NextDouble())) 'start of range + (size of range * random number between 0 and 1) randomDateValue = min + randomNumber End Sub
protected override void OnGenerateNextValues() { SqlDateTime min; SqlDateTime max; //Generate a random date from either range 1 or range 2. //Randomly select either range 1 or range 2 by randomly //generating an odd or an even random number. //------------------------------------------------------------ if (randomRange.Next() % 2 == 0) //check for odd or even { min = range1MinValue; max = range1MaxValue; } else { min = range2MinValue; max = range2MaxValue; } //The formula for creating a random number in a specific range is: //start of range + (size of range * random number between 0 and 1) //size of range TimeSpan range = max.Value - min.Value; //(size of range * random number between 0 and 1) TimeSpan randomNumber = new TimeSpan((long)(range.Ticks * random.NextDouble())); //start of range + (size of range * random number between 0 and 1) randomDateValue = min + randomNumber; }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Définition du convertisseur de type
Pour spécifier les propriétés d'entrée pour ce générateur de données dans l'explorateur de propriétés, vous devez fournir un convertisseur de type qui convertit les valeurs d'entrée vers et depuis le type SqlDateTime.
Pour créer la classe de convertisseur de type SqlDateTime
Dans le menu Projet, cliquez sur Ajouter une classe.
La boîte de dialogue Ajouter un nouvel élément s'affiche alors.
Dans la zone Nom, tapez SqlDateTimeConverter.
En haut de la fenêtre Code, avant la déclaration de classe, ajoutez les lignes de code suivantes :
Imports System.ComponentModel Imports System.Data.SqlTypes Imports System.Globalization
using System.ComponentModel; using System.Data.SqlTypes; using System.Globalization;
Renommez la classe Class1 en GeneratorDateRanges, puis indiquez qu'elle hérite de TypeConverter.
[Visual Basic] Public Class SqlDateTimeConverter Inherits TypeConverter End Class
public class SqlDateTimeConverter: TypeConverter { }
Dans la déclaration de classe, ajoutez le constructeur de classe. Si vous écrivez la classe de convertisseur de type dans Visual Basic, passez à étape 6.
public SqlDateTimeConverter() { }
Suivant le constructeur de classe, ajoutez une méthode qui vérifie si une conversion particulière est possible à l'aide de ce convertisseur de type.
Public Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean Dim result As Boolean result = False If (sourceType Is GetType(System.String)) Then result = True Else result = MyBase.CanConvertFrom(context, sourceType) End If Return result End Function Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean If (destinationType Is GetType(System.String)) Then Return True End If Return MyBase.CanConvertTo(context, destinationType) End Function
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { bool result = false; if (sourceType == typeof(string)) { result = true; } else { result = base.CanConvertFrom(context, sourceType); } return result; } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) { return true; } return base.CanConvertTo(context, destinationType); }
Enfin, ajoutez les méthodes du convertisseur.
Public Overrides Function ConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object Dim dateTimeString As String dateTimeString = value.ToString If (dateTimeString.Length > 0) Then Dim dateTime As Date dateTime = Date.Parse(dateTimeString, culture) Return New SqlDateTime(dateTime) End If Return MyBase.ConvertFrom(context, culture, value) End Function Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object If (destinationType Is GetType(System.String)) Then Dim dateTime As Date dateTime = CType(value, SqlDateTime).Value dateTime.ToString(culture) End If Return MyBase.ConvertTo(context, culture, value, destinationType) End Function
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { string dateTimeString = value as string; if (dateTimeString != null) { DateTime dateTime = DateTime.Parse(dateTimeString, culture); return new SqlDateTime(dateTime); } return base.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { DateTime dateTime = ((SqlDateTime)value).Value; dateTime.ToString(culture); } return base.ConvertTo(context, culture, value, destinationType); }
Dans le menu Fichier, cliquez sur Enregistrer tout.
Signature du générateur
Tous les générateurs de données personnalisés doivent être signés avec un nom fort avant d'être inscrits.
Pour signer le générateur avec un nom fort
Dans le menu Projet, cliquez sur Propriétés de GeneratorDateRanges pour ouvrir les propriétés du projet.
Sous l'onglet Signature, activez la case à cocher Signer l'assembly.
Dans la zone Choisir un fichier de clé de nom fort, cliquez sur <Nouveau...>.
Dans la zone Nom du fichier de clé, tapez GeneratorDateRangesKey, tapez et confirmez un mot de passe, puis cliquez sur OK.
Lorsque vous générez votre solution, le fichier de clé est utilisé pour signer l'assembly.
Dans le menu Fichier, cliquez sur Enregistrer tout.
Dans le menu Générer, cliquez sur Générer la solution.
Votre générateur de données a maintenant été généré. Vous devez ensuite l'inscrire sur votre ordinateur afin de pouvoir l'utiliser dans des plans de génération de données.
Sécurité
Pour plus d'informations, consultez Sécurité des générateurs de données.
Étapes suivantes
Maintenant que vous avez généré votre générateur de données, vous devez l'inscrire sur votre ordinateur. Pour plus d'informations, consultez l'une des rubriques suivantes :
Comment : enregistrer des générateurs de données personnalisés
Procédure pas à pas : enregistrement d'un générateur de données personnalisé
Voir aussi
Tâches
Procédure pas à pas : déploiement d'un générateur de données personnalisé
Concepts
Vue d'ensemble de l'extensibilité des générateurs de données
Référence
Microsoft.VisualStudio.TeamSystem.Data.DataGenerator
Autres ressources
Création de générateurs de données personnalisés