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
En Visual Studio, cree un proyecto de Biblioteca de clases en el lenguaje que prefiera y asígnele el nombre GeneratorDateRanges.
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.
(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.
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;
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 { }
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.
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. 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;} }
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.
Dim randomDateValue As SqlDateTime
SqlDateTime randomDateValue;
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;} }
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
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;
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); }
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
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; }
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
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.
[Visual Basic] 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 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); }
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); }
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 GeneratorDateRanges 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 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.
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