Compartir a través de


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

  1. En Visual Studio, cree un proyecto de Biblioteca de clases en el lenguaje que prefiera y asígnele el nombre GeneratorDateRanges2.

  2. En el menú Proyecto, haga clic en Agregar referencia.

    Aparecerá el cuadro de diálogo Agregar referencia.

  3. 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.

  4. En el menú Proyecto, haga clic en Agregar referencia.

    Aparecerá el cuadro de diálogo Agregar referencia.

  5. Haga clic en la ficha Examinar y vaya a ...\Archivos de programa\Microsoft Visual Studio 9,0\DBPro\Extensions.

  6. Haga clic en Microsoft.VisualStudio.TeamSystem.Data.Generators.dll y después haga clic en Aceptar.

  7. (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.

  8. 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;
    
  9. 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
    {
    }
    
  10. 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

  1. 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;
    
  2. 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;}
    }
    
  3. 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

  1. 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;
    
  2. 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;}
    }
    
  3. En el menú Archivo, haga clic en Guardar todo.

Reemplazar el método OnInitialize

Para reemplazar el método OnInitialize

  1. 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;
    
  2. 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();
    
  3. 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);
    }
    
  4. En el menú Archivo, haga clic en Guardar todo.

Reemplazar otros métodos

Para reemplazar otros métodos

  1. 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();
    }
    
  2. 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();
    }
    
  3. 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);
    }
    
  4. 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

  1. 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();
    }
    
  2. 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

  1. En el menú Proyecto, haga clic en Agregar clase.

    Aparecerá el cuadro de diálogo Agregar nuevo elemento.

  2. En Nombre, escriba SqlDateTimeConverter.

  3. 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;
    
  4. 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
    {
    }
    
  5. 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()
    {
    }
    
  6. 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;
    }
    
  7. 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);
            }
    
  8. 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

  1. En el menú Proyecto, haga clic en Propiedades de GeneratorDateRanges2 para abrir las propiedades del proyecto.

  2. En la ficha Firma, active la casilla Firmar el ensamblado.

  3. En el cuadro Seleccione un archivo de clave de nombre seguro, haga clic en <Nuevo...>.

  4. 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.

  5. En el menú Archivo, haga clic en Guardar todo.

  6. 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

Utilizar generadores de datos estándar

Tutoriales acerca del generador de datos