Tutorial: Crear un generador de datos personalizado que agregue generadores de datos estándar
Actualización: noviembre 2007
En Visual Studio Team System Database puede crear instancias de las clases de generador de datos estándar en las clases de generador de datos personalizado. Este enfoque permite reducir de forma significativa la cantidad de lógica que hay que incluir en los generadores de datos personalizados. Por ejemplo, podría querer crear un generador para generar datos aleatorios de cadena que coincidan con varios modelos complejos. Puede crear un generador de datos personalizado que contenga la lógica para controlar los distintos modelos y el generador Expresión regular estándar para controlar la coincidencia con modelos complejos.
En este tutorial va a crear un generador de datos personalizado que agregue el generador DateTime estándar. Tiene que crear un generador que genere datos que estén dentro de uno de dos intervalos de fechas distintos. El generador acepta dos intervalos distintos como entrada y genera una fecha aleatoria que está dentro de uno de los dos intervalos.
Nota: |
---|
Para obtener más información sobre el objetivo de este generador de datos personalizado y para aprender a alcanzar el mismo objetivo mediante extensibilidad normal, vea Tutorial: Crear un generador de datos personalizado para una restricción CHECK. |
En este tutorial realizará las tareas siguientes:
Crear una clase que herede de Generator.
Crear propiedades de entrada que permitan al usuario especificar los dos intervalos de fechas.
Crear una propiedad de salida para usarla como salida del generador.
Crear dos instancias del generador DateTime estándar para que representen cada uno de los dos intervalos posibles.
Reemplazar los métodos Generator y, en ellos, delegar el trabajo en generadores estándar.
Firmar el generador con un nombre seguro.
Requisitos previos
Para realizar este tutorial, necesita lo siguiente:
- Database Edition
Crear la clase de generador de datos personalizado
Para crear la clase de generador de datos personalizado
En Visual Studio, cree un proyecto de Biblioteca de clases en el lenguaje que prefiera y asígnele el nombre GeneratorDateRanges2.
En el menú Proyecto, haga clic en Agregar referencia.
Aparecerá el cuadro de diálogo Agregar referencia.
Haga clic en la ficha .NET. En la lista Nombre de componente haga clic en Microsoft.VisualStudio.TeamSystem.Data y, a continuación, haga clic en Aceptar.
En el menú Proyecto, haga clic en Agregar referencia.
Aparecerá el cuadro de diálogo Agregar referencia.
Haga clic en la ficha Examinar y vaya a ...\Archivos de programa\Microsoft Visual Studio 9,0\DBPro\Extensions.
Haga clic en Microsoft.VisualStudio.TeamSystem.Data.Generators.dll y después haga clic en Aceptar.
(Opcional, sólo en Visual Basic) En el Explorador de soluciones, haga clic en Mostrar todos los archivos y expanda el nodo Referencias para comprobar las nuevas referencias.
En la parte superior de la ventana Código, agregue la siguiente línea de código antes de la declaración de clase.
Imports Microsoft.VisualStudio.TeamSystem.Data.DataGenerator Imports Microsoft.VisualStudio.TeamSystem.Data.Generators Imports System.Data.SqlTypes
using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator; using Microsoft.VisualStudio.TeamSystem.Data.Generators; using System.Data.SqlTypes;
Cambie el nombre de la clase de Class1 a GeneratorDateRanges2 y especifique que la clase hereda de Generator, como se indica en el siguiente ejemplo.
Precaución: De manera predeterminada, el nombre que asigne a la clase es el que aparecerá en la lista de la columna Generador en la ventana Detalles de columna. Debe especificar un nombre que no entre en conflicto con el nombre de un generador estándar o de otro generador personalizado.
Public Class GeneratorDateRanges2 Inherits Generator End Class
public class GeneratorDateRanges2: Generator { }
En el menú Archivo, haga clic en Guardar todo.
Agregar las propiedades de entrada
Este generador de datos personalizado acepta dos intervalos de fechas como entrada. Para especificar cada intervalo, el usuario debe especificar las fechas límite. Por tanto, debe crear cuatro propiedades de entrada en total: dos fechas iniciales y dos fechas finales.
Para agregar las propiedades de entrada
Cree cuatro variables miembro para las fechas límite de los dos intervalos de fechas, como se indica en el siguiente ejemplo.
Dim range1MinValue As SqlDateTime Dim range1MaxValue As SqlDateTime Dim range2MinValue As SqlDateTime Dim range2MaxValue As SqlDateTime
SqlDateTime range1MinValue; SqlDateTime range1MaxValue; SqlDateTime range2MinValue; SqlDateTime range2MaxValue;
Cree cuatro propiedades para establecer las fechas límite de los dos intervalos de fechas, como se indica en el siguiente ejemplo. Las propiedades deben tener el atributo InputAttribute para identificarse como propiedades de entrada.
<Input(Visible:= true, 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(Visible:= true, 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(Visible:= true, 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(Visible:= true, 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(Visible = true, TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range1Min { set {range1MinValue = value;} get {return range1MinValue;} } [Input(Visible = true, TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range1Max { set {range1MaxValue = value;} get {return range1MaxValue;} } [Input(Visible = true, TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range2Min { set {range2MinValue = value;} get {return range2MinValue;} } [Input(Visible = true, TypeConverter = typeof(SqlDateTimeConverter))] public SqlDateTime Range2Max { set {range2MaxValue = value;} get {return range2MaxValue;} }
En el menú Archivo, haga clic en Guardar todo.
Agregar la propiedad de salida
Este generador de datos personalizado devuelve una fecha aleatoria como salida. Por tanto, debe crear una propiedad de salida.
Para agregar la propiedad de salida
Cree una variable miembro para la fecha aleatoria que constituye la salida, como se muestra en el ejemplo siguiente.
Dim randomDateValue As SqlDateTime
SqlDateTime randomDateValue;
Cree una propiedad para devolver la fecha aleatoria como salida, como se indica en el ejemplo siguiente. La propiedad debe tener el atributo OutputAttribute para identificarse como una propiedad de salida.
<Output()> _ Public ReadOnly Property RandomDate() As SqlDateTime Get Return randomDateValue End Get End Property
[Output] public SqlDateTime RandomDate { get {return randomDateValue;} }
En el menú Archivo, haga clic en Guardar todo.
Reemplazar el método OnInitialize
Para reemplazar el método OnInitialize
Cree una variable miembro para generar números aleatorios, como se indica en el siguiente ejemplo. Esta variable elige aleatoriamente entre los dos intervalos de fechas posibles.
Dim randomRange As Random
Random randomRange;
Cree dos variables miembro que sean generadores DateTime estándar y genere instancias de las mismas, como se indica en el siguiente ejemplo.
Dim range1 As DatabaseDateTime = New DatabaseDateTime() Dim range2 As DatabaseDateTime = New DatabaseDateTime()
DatabaseDateTime range1 = new DatabaseDateTime(); DatabaseDateTime range2 = new DatabaseDateTime();
Reemplace el método OnInitialize, como se indica en el siguiente ejemplo. En este método debe establecer el valor de inicialización del objeto Random y hacer que el generador sea determinista. También debe llamar al método Initialize de los generadores estándar.
Protected Overrides Sub OnInitialize(ByVal initInfo As GeneratorInit) randomRange = New Random(Me.Seed) 'deterministic range1.Initialize(initInfo) range2.Initialize(initInfo) MyBase.OnInitialize(initInfo) End Sub
protected override void OnInitialize(GeneratorInit initInfo) { randomRange = new Random(this.Seed); //deterministic range1.Initialize(initInfo); range2.Initialize(initInfo); base.OnInitialize(initInfo); }
En el menú Archivo, haga clic en Guardar todo.
Reemplazar otros métodos
Para reemplazar otros métodos
Reemplace OnSetInputValues, como se indica en el siguiente ejemplo. El parámetro inputs de este método es un objeto IDictionary con todas las propiedades del generador estándar establecidas por el usuario, como Valor de inicialización y Porcentaje de valores null. Debe llamar a los métodos SetInputValues de los generadores estándar para pasarles estos valores. Después debe establecer las propiedades Mín y Máx de cada generador estándar con las propiedades de entrada personalizadas que creó en este generador de datos.
Protected Overrides Sub OnSetInputValues(ByVal inputs As IDictionary(Of String, Object)) 'It is important to call MyBase.OnSetInputValues first to get the inputs 'from the Properties window first. '-------------------------------------------------------------------------- MyBase.OnSetInputValues(inputs) range1.SetInputValues(inputs) range2.SetInputValues(inputs) range1.Min = range1MinValue range1.Max = range1MaxValue range2.Min = range2MinValue range2.Max = range2MaxValue range1.Distribution = New Uniform() range2.Distribution = New Uniform() End Sub
protected override void OnSetInputValues(IDictionary<string, object> inputs) { //It is important to call base.OnSetInputValues first to get the inputs //from the Properties window first. //------------------------------------------------------------------------- base.OnSetInputValues(inputs); range1.SetInputValues(inputs); range2.SetInputValues(inputs); range1.Min = range1MinValue; range1.Max = range1MaxValue; range2.Min = range2MinValue; range2.Max = range2MaxValue; range1.Distribution = new Uniform(); range2.Distribution = new Uniform(); }
Reemplace OnValidateInputs para validar las entradas, como se indica en el siguiente ejemplo.
Protected Overrides Sub OnValidateInputs() range1.ValidateInputs() range2.ValidateInputs() MyBase.OnValidateInputs() End Sub
protected override void OnValidateInputs() { range1.ValidateInputs(); range2.ValidateInputs(); base.OnValidateInputs(); }
Reemplace el método Dispose(Boolean) para limpiar los generadores estándar, como se indica en el siguiente ejemplo.
Protected Overrides Sub Dispose(ByVal disposing As Boolean) range1.Dispose() range2.Dispose() MyBase.Dispose(disposing) End Sub
protected override void Dispose(bool disposing) { range1.Dispose(); range2.Dispose(); base.Dispose(disposing); }
En el menú Archivo, haga clic en Guardar todo.
Reemplazar el método OnGenerateNextValues
Database Edition llama al método OnGenerateNextValues del generador para crear los datos que necesita. Debe reemplazar este método para proporcionar la lógica que genere la fecha aleatoria para la propiedad de salida. En este tutorial se delega la responsabilidad de generar la fecha aleatoria en el generador DateTime estándar.
Para reemplazar el método OnGenerateNextValues
Reemplace el método OnGenerateNextValues, como se indica en el siguiente ejemplo.
Protected Overrides Sub OnGenerateNextValues() '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 'the standard generator does the work range1.GenerateNextValues() randomDateValue = range1.Result.Value Else 'the standard generator does the work range2.GenerateNextValues() randomDateValue = range2.Result.Value End If MyBase.OnGenerateNextValues() End Sub
protected override void OnGenerateNextValues() { //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 { //the standard generator does the work range1.GenerateNextValues(); randomDateValue = range1.Result.Value; } else { //the standard generator does the work range2.GenerateNextValues(); randomDateValue = range2.Result.Value; } base.OnGenerateNextValues(); }
En el menú Archivo, haga clic en Guardar todo.
Definir el convertidor de tipos
Para especificar las propiedades de entrada de este generador de datos en la ventana Propiedades, debe proporcionar un convertidor de tipos que convierta los valores de entrada al tipo SqlDateTime y viceversa.
Para crear la clase de convertidor de tipos SqlDateTime
En el menú Proyecto, haga clic en Agregar clase.
Aparecerá el cuadro de diálogo Agregar nuevo elemento.
En Nombre, escriba SqlDateTimeConverter.
En la parte superior de la ventana Código, agregue las siguientes líneas de código antes de la declaración de clase.
Imports System.ComponentModel Imports System.Data.SqlTypes Imports System.Globalization
using System.ComponentModel; using System.Data.SqlTypes; using System.Globalization;
Cambie el nombre de la clase de Class1 a GeneratorDateRanges y especifique que la clase hereda de TypeConverter.
Public Class SqlDateTimeConverter Inherits TypeConverter End Class
public class SqlDateTimeConverter: TypeConverter { }
En la declaración de clase, agregue el constructor de clase. Si está escribiendo la clase del convertidor de tipos en Visual Basic, omita el paso 6.
public SqlDateTimeConverter() { }
A continuación del constructor de clase, agregue un método que compruebe si este convertidor de tipos puede realizar una determinada conversión.
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 override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { bool result = false; if (sourceType == typeof(string)) { result = true; } else { result = base.CanConvertFrom(context, sourceType); } return result; }
Finalmente, agregue los métodos del convertidor.
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 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 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 bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) { return true; } return base.CanConvertTo(context, destinationType); } 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); }
En el menú Archivo, haga clic en Guardar todo.
Firmar el generador
Todos los generadores de datos personalizados deben firmarse con un nombre seguro antes de registrarse.
Para firmar el generador con un nombre seguro
En el menú Proyecto, haga clic en Propiedades de GeneratorDateRanges2 para abrir las propiedades del proyecto.
En la ficha Firma, active la casilla Firmar el ensamblado.
En el cuadro Seleccione un archivo de clave de nombre seguro, haga clic en <Nuevo...>.
En el cuadro Nombre del archivo de clave, escriba GeneratorDateRanges2Key, escriba y confirme la contraseña y, a continuación, haga clic en Aceptar.
Al generar la solución, se usa el archivo de clave para firmar el ensamblado.
En el menú Archivo, haga clic en Guardar todo.
En el menú Generar, haga clic en Generar solución.
Se crea el generador de datos. A continuación debe registrarlo en su equipo para poder usarlo en los planes de generación de datos.
Seguridad
Para obtener más información, vea Seguridad de los generadores de datos.
Pasos siguientes
Ahora que ha creado el generador de datos, debe registrarlo en su equipo. Para obtener más información, vea uno de los temas siguientes:
Vea también
Tareas
Tutorial: Implementar un generador de datos personalizado
Conceptos
Descripción general de la extensibilidad del Generador de datos
Referencia
Microsoft.VisualStudio.TeamSystem.Data.DataGenerator
Otros recursos
Crear generadores de datos personalizados