다음을 통해 공유


연습: 표준 생성기를 집계하는 사용자 지정 데이터 생성기 만들기

업데이트: 2007년 11월

Visual Studio Team System Database Edition에서는 사용자 지정 데이터 생성기 클래스 내에서 표준 데이터 생성기 클래스의 인스턴스를 만들 수 있습니다. 이 방법을 사용하면 사용자 지정 데이터 생성기에 포함해야 하는 논리의 양을 간편하게 줄일 수 있습니다. 예를 들어 둘 이상의 복잡한 패턴에 맞는 무작위 문자열 데이터를 생성하는 생성기를 만들 수 있습니다. 이러한 경우 여러 패턴을 처리하는 논리가 들어 있는 사용자 지정 데이터 생성기를 만든 다음 표준 RegularExpression 생성기를 사용하여 복잡한 패턴 일치 작업을 처리할 수 있습니다.

이 연습에서는 표준 DateTime 생성기를 집계하는 사용자 지정 데이터 생성기를 만듭니다. 즉, 서로 다른 두 날짜 범위 중 하나에 포함된 날짜를 생성하는 생성기를 만듭니다. 이 생성기에서는 서로 다른 두 범위를 입력으로 받아 두 범위 중 하나에 포함되는 무작위 날짜를 생성합니다.

참고:

이 사용자 지정 데이터 생성기의 목적 및 일반 확장성을 사용하여 같은 작업을 수행하는 방법에 대한 자세한 내용은 연습: CHECK 제약 조건에 맞는 사용자 지정 데이터 생성기 만들기를 참조하십시오.

이 연습에서는 다음 작업을 수행합니다.

  • Generator에서 상속된 클래스를 만듭니다.

  • 사용자가 두 날짜 범위를 지정할 수 있는 입력 속성을 만듭니다.

  • 생성기 출력으로 사용할 출력 속성을 만듭니다.

  • 사용 가능한 두 범위를 각각 나타내는 표준 DateTime 생성기의 두 인스턴스를 만듭니다.

  • Generator 메서드를 재정의하고 이 메서드 내에서 표준 생성기에 작업을 위임합니다.

  • 강력한 이름으로 생성기에 서명합니다.

사전 요구 사항

이 연습을 완료하려면 다음이 필요합니다.

  • Database Edition

사용자 지정 데이터 생성기 클래스 만들기

사용자 지정 데이터 생성기 클래스를 만들려면

  1. Visual Studio에서 원하는 언어로 클래스 라이브러리 프로젝트를 만들고 이름을 GeneratorDateRanges2로 지정합니다.

  2. 프로젝트 메뉴에서 참조 추가를 클릭합니다.

    참조 추가 대화 상자가 나타납니다.

  3. .NET 탭을 클릭합니다. 구성 요소 이름 목록에서 Microsoft.VisualStudio.TeamSystem.Data를 클릭한 다음 확인을 클릭합니다.

  4. 프로젝트 메뉴에서 참조 추가를 클릭합니다.

    참조 추가 대화 상자가 나타납니다.

  5. 찾아보기 탭을 클릭하고 ...\Program Files\Microsoft Visual Studio 9.0\DBPro\Extensions 위치로 이동합니다.

  6. Microsoft.VisualStudio.TeamSystem.Data.Generators.dll을 클릭한 다음 확인을 클릭합니다.

  7. Visual Basic의 경우 필요에 따라 솔루션 탐색기에서 모든 파일 표시를 클릭하고 참조 노드를 확장하여 새 참조를 확인합니다.

  8. 코드 창의 맨 위에서 클래스 선언 앞에 다음 코드 줄을 추가합니다.

    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. 다음 예제와 같이 클래스 이름을 Class1에서 GeneratorDateRanges2로 바꾸고 클래스가 Generator에서 상속되도록 지정합니다.

    주의:

    기본적으로 클래스에 지정하는 이름은 열 정보 창의 생성기 열에 있는 목록에 표시되는 이름입니다. 이때 표준 생성기 또는 다른 사용자 지정 생성기와 충돌하지 않는 이름을 지정해야 합니다.

    Public Class GeneratorDateRanges2
        Inherits Generator
    
    End Class
    
    public class GeneratorDateRanges2: Generator
    {
    }
    
  10. 파일 메뉴에서 모두 저장을 클릭합니다.

입력 속성 추가

이 사용자 지정 데이터 생성기에서는 두 날짜 범위를 입력받습니다. 사용자는 각 범위의 최소 및 최대 날짜를 지정하여 범위를 지정합니다. 따라서 두 개의 최소 날짜와 두 개의 최대 날짜, 즉 모두 네 개의 입력 속성을 만들어야 합니다.

입력 속성을 추가하려면

  1. 다음 예제와 같이 두 날짜 범위의 최소 날짜와 최대 날짜를 저장할 네 개의 멤버 변수를 만듭니다.

    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. 다음 예제와 같이 두 날짜 범위의 최소 날짜와 최대 날짜를 설정할 네 개의 속성을 만듭니다. 이러한 속성에는 입력 속성임을 식별하는 InputAttribute가 있어야 합니다.

    <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. 파일 메뉴에서 모두 저장을 클릭합니다.

출력 속성 추가

이 사용자 지정 데이터 생성기에서는 하나의 무작위 날짜를 출력으로 반환합니다. 따라서 하나의 출력 속성을 만들어야 합니다.

출력 속성을 추가하려면

  1. 다음 예제와 같이 출력 값인 무작위 날짜를 저장할 멤버 변수를 만듭니다.

    Dim randomDateValue As SqlDateTime
    
    SqlDateTime randomDateValue;
    
  2. 다음 예제와 같이 무작위 날짜를 출력으로 반환할 속성을 만듭니다. 이 속성에는 출력 속성임을 식별하는 OutputAttribute가 있어야 합니다.

    <Output()> _
    Public ReadOnly Property RandomDate() As SqlDateTime
        Get
            Return randomDateValue
        End Get
    End Property
    
    [Output]
    public SqlDateTime RandomDate
    {
        get {return randomDateValue;}
    }
    
  3. 파일 메뉴에서 모두 저장을 클릭합니다.

OnInitialize 메서드 재정의

OnInitialize 메서드를 재정의하려면

  1. 다음 예제와 같이 난수를 생성할 멤버 변수를 만듭니다. 이 변수에서는 사용 가능한 두 날짜 범위 중 하나를 선택합니다.

    Dim randomRange As Random
    
    Random randomRange;
    
  2. 다음 예제와 같이 표준 DateTime 생성기인 두 멤버 변수를 만들고 인스턴스화합니다.

    Dim range1 As DatabaseDateTime = New DatabaseDateTime()
    Dim range2 As DatabaseDateTime = New DatabaseDateTime()
    
    DatabaseDateTime range1 = new DatabaseDateTime();
    DatabaseDateTime range2 = new DatabaseDateTime();
    
  3. 다음 예제와 같이 OnInitialize 메서드를 재정의합니다. 이 메서드에서는 Random 개체의 시드 값을 지정하여 생성기를 명확하게 만듭니다. 또한 표준 생성기의 Initialize 메서드를 호출합니다.

    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. 파일 메뉴에서 모두 저장을 클릭합니다.

기타 메서드 재정의

기타 메서드를 재정의하려면

  1. 다음 예제와 같이 OnSetInputValues를 재정의합니다. 이 메서드의 inputs 매개 변수는 사용자가 설정한 시드 및 Null 비율 등의 모든 표준 생성기 속성이 들어 있는 IDictionary입니다. 표준 생성기의 SetInputValues 메서드를 호출하여 이러한 값을 표준 생성기에 전달합니다. 그런 다음 각 표준 생성기의 Min 및 Max 속성을 이 데이터 생성기에서 만든 사용자 지정 입력 속성으로 설정합니다.

    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. 다음 예제와 같이 OnValidateInputs 메서드를 재정의하여 입력 값의 유효성을 검사합니다.

    Protected Overrides Sub OnValidateInputs()
    
        range1.ValidateInputs()
        range2.ValidateInputs()
    
        MyBase.OnValidateInputs()
    End Sub
    
    protected override void OnValidateInputs()
    {
        range1.ValidateInputs();
        range2.ValidateInputs();
    
        base.OnValidateInputs();
    }
    
  3. 다음 예제와 같이 Dispose(Boolean) 메서드를 재정의하여 표준 생성기를 정리합니다.

    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. 파일 메뉴에서 모두 저장을 클릭합니다.

OnGenerateNextValues 메서드 재정의

Database Edition에서는 생성기의 OnGenerateNextValues 메서드를 호출하여 필요한 데이터를 만듭니다. 출력 속성에 사용할 무작위 날짜를 생성하는 논리를 제공하려면 이 메서드를 재정의해야 합니다. 이 연습에서는 무작위 날짜를 생성하는 작업을 표준 DateTime 생성기에 위임합니다.

OnGenerateNextValues 메서드를 재정의하려면

  1. 다음 예제와 같이 OnGenerateNextValues 메서드를 재정의합니다.

    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. 파일 메뉴에서 모두 저장을 클릭합니다.

형식 변환기 정의

속성 창에서 이 데이터 생성기에 대해 입력 속성을 지정하려면 입력 값과 SqlDateTime 형식 간을 변환하는 형식 변환기를 제공해야 합니다.

SqlDateTime 형식 변환기 클래스를 만들려면

  1. 프로젝트 메뉴에서 클래스 추가를 클릭합니다.

    새 항목 추가 대화 상자가 나타납니다.

  2. 이름에 SqlDateTimeConverter를 입력합니다.

  3. 코드 창의 맨 위에서 클래스 선언 앞에 다음 코드 줄을 추가합니다.

    Imports System.ComponentModel
    Imports System.Data.SqlTypes
    Imports System.Globalization
    
    using System.ComponentModel;
    using System.Data.SqlTypes;
    using System.Globalization;
    
  4. 클래스 이름을 Class1에서 GeneratorDateRanges로 바꾸고 클래스가 TypeConverter에서 상속되도록 지정합니다.

    Public Class SqlDateTimeConverter
        Inherits TypeConverter
    
    End Class
    
    public class SqlDateTimeConverter: TypeConverter
    {
    }
    
  5. 클래스 선언 내에 클래스 생성자를 추가합니다. Visual Basic에서 형식 변환기 클래스를 작성 중인 경우에는 6단계로 건너뜁니다.

    public SqlDateTimeConverter()
    {
    }
    
  6. 형식 생성자 다음에 이 형식 변환기가 특정 변환을 수행할 수 있는지 여부를 확인하는 메서드를 추가합니다.

    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. 마지막으로 변환기 메서드를 추가합니다.

    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. 파일 메뉴에서 모두 저장을 클릭합니다.

생성기 서명

모든 사용자 지정 데이터 생성기는 등록하기 전에 강력한 이름으로 서명되어야 합니다.

강력한 이름을 사용하여 생성기에 서명하려면

  1. 프로젝트 메뉴에서 GeneratorDateRanges2 속성을 클릭하여 프로젝트 속성을 엽니다.

  2. 서명 탭에서 어셈블리 서명 확인란을 선택합니다.

  3. 강력한 이름 키 파일 선택 상자에서 <새로 만들기...>를 클릭합니다.

  4. 키 파일 이름 상자에 GeneratorDateRanges2Key를 입력하고 암호를 입력 및 확인한 다음 확인을 클릭합니다.

    솔루션을 빌드할 때 이 키 파일이 어셈블리에 서명하는 데 사용됩니다.

  5. 파일 메뉴에서 모두 저장을 클릭합니다.

  6. 빌드 메뉴에서 솔루션 빌드를 클릭합니다.

    이제 데이터 생성기가 빌드되었습니다. 다음으로는 생성기를 데이터 생성 계획에서 사용할 수 있도록 컴퓨터에 등록해야 합니다.

보안

자세한 내용은 데이터 생성기 보안을 참조하십시오.

다음 단계

이제 생성기가 빌드되었으므로 컴퓨터에 등록해야 합니다. 자세한 내용은 다음 중 하나를 참조하십시오.

참고 항목

작업

연습: 사용자 지정 데이터 생성기 배포

개념

데이터 생성기 확장성 개요

참조

Microsoft.VisualStudio.TeamSystem.Data.DataGenerator

기타 리소스

사용자 지정 데이터 생성기 만들기

표준 데이터 생성기 사용

데이터 생성기 연습