Compartir a través de


Tutorial: Crear un generador de datos personalizado para una restricción CHECK

Actualización: noviembre 2007

Puede usar generadores de datos estándar para rellenar columnas con datos en Visual Studio Team System Database. Si la columna que desea rellenar tiene una restricción CHECK definida, los datos con los que se va a rellenar la columna deben satisfacer la restricción. Los generadores de datos estándar pueden generar datos que satisfacen muchas restricciones CHECK. Por ejemplo, si tiene una restricción CHECK que requiere que una fecha esté dentro de un intervalo determinado, puede usar el generador DateTime estándar y establecer las propiedades Mín y Máx de forma que satisfagan la restricción.

Sin embargo, los generadores de datos estándar no pueden satisfacer todas las restricciones CHECK. Por ejemplo, si tiene una restricción CHECK que requiere que una fecha esté en uno de dos intervalos distintos, no puede usar el generador DateTime estándar. En este tutorial va a crear un generador de datos personalizado que puede satisfacer una restricción de este tipo. El generador acepta dos intervalos como entrada y genera una fecha aleatoria que está dentro de uno de los intervalos.

Nota:

Puede usar otro enfoque para crear un generador de datos personalizado y alcanzar el mismo objetivo mediante extensibilidad de agregación. Para obtener más información, vea Tutorial: Crear un generador de datos personalizado que agregue generadores de datos estándar.

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.

  • Reemplazar el método OnInitialize para establecer el valor de inicialización de los objetos Random y hacer que el generador sea determinista.

  • Reemplazar el método OnGenerateNextValues para generar los datos.

  • 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 GeneratorDateRanges.

  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. (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 la nueva referencia.

  5. 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 System.Data.SqlTypes
    
    using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator;
    using System.Data.SqlTypes;
    
  6. Cambie el nombre de la clase de Class1 a GeneratorDateRanges y especifique que la clase hereda de Generator.

    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 GeneratorDateRanges
        Inherits Generator
    
    End Class
    
    public class GeneratorDateRanges: Generator
    {
    }
    
  7. 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.

    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. Las propiedades deben tener el atributo InputAttribute para identificarse como propiedades de entrada.

    <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;}
    }
    
  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.

    Dim randomDateValue As SqlDateTime
    
    SqlDateTime randomDateValue;
    
  2. Cree una propiedad para devolver la fecha aleatoria como salida. 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

Los datos aleatorios pueden generarse de forma determinista o no determinista. En la generación de datos determinista se repiten los mismos datos cada vez que se usa el mismo valor de inicialización. Todos los generadores de datos tienen una propiedad Seed cuyo valor puede ser establecido por el usuario. Puede reemplazar el método OnInitialize para establecer el valor de inicialización de los objetos Random y hacer que el generador sea determinista.

Para reemplazar el método OnInitialize

  1. Cree dos variables miembro para generar números aleatorios, como se indica en el siguiente ejemplo. Una variable genera una fecha aleatoria. La otra variable elige aleatoriamente entre los dos intervalos de fechas posibles.

    Dim random As Random
    Dim randomRange As Random
    
    Random random;
    Random randomRange;
    
  2. Reemplace el método 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);
    }
    
  3. 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 invalidar este método para proporcionar la lógica que genere la fecha aleatoria para la propiedad de salida.

Para reemplazar el método OnGenerateNextValues

  1. Reemplace el método OnGenerateNextValues, como se indica el siguiente ejemplo.

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

Definir el convertidor de tipos

Para especificar las propiedades de entrada para este generador de datos en el explorador de 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.

     [Visual Basic]
    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 es posible una conversión determinada por este convertidor de tipos.

    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);
    }
    
  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 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);
            }
    
  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 GeneratorDateRanges 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 GeneratorDateRangesKey, 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