演练:创建自定义数据生成器

在开发数据库架构时,可以通过用尽可能接近于生产数据的数据填充测试数据库,更加有效地测试所建议的更改。 与内置的数据生成器相比,自定义数据生成器提供能够更准确地满足您的规范的测试数据。 例如,可以创建一个生成器,以便用所指定列表中的随机字符串或者用所指定范围中的数字来填充表列。 有关更多信息,请参见数据生成器扩展性概述

在此分步主题中,您将创建用于生成自定义地址字符串的自定义数据生成器。 在本演练中,您将执行以下任务:

  1. 为自定义地址数据生成器创建一个从 Generator 继承的类库。

  2. 添加要用作生成器输出的输出属性。

  3. 重写 OnGenerateNextValues 方法以生成数据。

  4. 对生成器程序集进行签名。

  5. 创建与用于注册的程序集关联的 XML 文件。

  6. 创建一个数据库项目和一个数据生成计划以测试自定义数据生成器。

系统必备

必须安装 Visual Studio 高级专业版或 Visual Studio 旗舰版才能完成本演练。

为自定义生成器创建一个类库

第一步是为自定义地址数据生成器创建一个类库。

为自定义生成器创建类库

  1. 创建一个 Visual C# 类库项目,并将其命名为 SampleGenerator。

  2. 在**“解决方案资源管理器”中右击项目,再单击“添加引用”**。

  3. 单击**“.NET”**选项卡。

  4. 在**“组件名称”**列中,选择以下组件:

    • Microsoft.Data.Schema

    • Microsoft.Data.Schema.Sql

    • Microsoft.Data.Schema.Tools

    提示

    按住 Ctrl 键同时单击,以选择多个组件。

  5. 选择了所有所需的组件后,单击**“确定”**。

    此时将在**“解决方案资源管理器”中该项目的“引用”**节点下显示所选的引用。

  6. 在**“代码”**窗口顶部的类声明之前,添加下面的代码行:

    using Microsoft.Data.Schema.Tools.DataGenerator;
    using Microsoft.Data.Schema.Extensibility;
    using Microsoft.Data.Schema;
    using Microsoft.Data.Schema.Sql;
    
  7. 将 Class1 类重命名为 AddressGenerator。

    警告

    默认情况下,为该类指定的名称将显示在“列详细信息”窗口上的“生成器”列中。 所指定的名称不应当与内置生成器或其他自定义生成器的名称冲突。

    public class AddressGenerator
    {
    }
    
  8. 指定从 Generator 继承类,如下面的示例所示:

    public class AddressGenerator : Generator
    {
    }
    
  9. 添加 DatabaseSchemaProviderCompatibilityAttribute,如下面的示例所示:

    [DatabaseSchemaProviderCompatibility(typeof(SqlDatabaseSchemaProvider))]
    public class AddressGenerator : Generator
    {
    }
    

    有关扩展兼容性特性的更多信息,请参见扩展 Visual Studio 的数据库功能

  10. 在**“文件”菜单上,单击“全部保存”**。

将输出属性添加到生成器中

在上一节中,您创建了一个从 Generator 类继承的类库。 在本节中,将向该类中添加输出属性。 输出属性包含生成的数据的值。 输出属性还指定此生成器可以生成的数据类型。

添加输出属性

  1. 创建将用于生成地址的成员变量,如下面的示例所示。

    在后面的步骤中,将在输出属性中使用 _address 变量。

    private Random _random;
    private string _street;
    private string _city;
    private string _state;
    private int _zipCode;
    private string _address;
    
    private static readonly List<String> _states =
                new List<string>() { "AK", "AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY" };
    
  2. 为 _random 成员变量创建一个私有属性,如下面的示例所示:

    private Random Random
            {
                get
                {
                    if (_random == null)
                        _random = new Random(base.Seed);
    
                    return _random;
                }
            }
    
  3. 为 _address 成员变量创建一个公共属性,并向该属性中添加 OutputAttribute,如下面的示例所示:

    [Output(Description = "Generates street and city values of \"2150 Newton Street, San Francisco\", with random state and zip code.", Name = "Address")]
            public string Address
            {
                get
                {
                    return this._address;
                }
            }
    
  4. 在**“文件”菜单上,单击“全部保存”**。

重写 OnGenerateNextValues 方法

Visual Studio 为其需要的每组值调用每个生成器的 OnGenerateNextValues 方法。 创建数据生成器时,应重写此方法以提供为每个输出属性生成值的逻辑。

重写 OnGenerateNextValues 方法

  1. 重写 OnGenerateNextValues 方法,如下面的示例所示:

    protected override void OnGenerateNextValues()
    {
        this._street = "2150 Newton Street";
                this._city = "San Francisco";
                this._state = _states[Random.Next(0, _states.Count)];
                this._zipCode = Int32.Parse(String.Format("{0}{1}{2}{3}{4}", GetRandomDigit(1), GetRandomDigit(), GetRandomDigit(), GetRandomDigit(), GetRandomDigit()));
                this._address = String.Format("{0}, {1}, {2} {3}", _street, _city, _state, _zipCode);
    }
    
  2. 添加以下方法,在为 _zipcode 变量创建值时将使用这些方法:

    private int GetRandomDigit()
            {
                return GetRandomDigit(0);
            }
    
            private int GetRandomDigit(int lowNumber)
            {
                return Random.Next(lowNumber, 10);
            }
    
  3. 在**“文件”菜单上,单击“全部保存”**。

对生成器进行签名

接下来,您必须使用强名称对自定义数据生成器进行签名。

使用强名称对生成器进行签名

  1. 在**“项目”菜单上,单击“SampleGenerator 属性”**。

  2. 在**“签名”选项卡上,选中“为程序集签名”**复选框。

  3. 在**“选择强名称密钥文件”框中,单击“<新建...>”**。

    将显示**“创建强名称密钥”**对话框。

  4. 在**“密钥文件名称”**框中,键入 SampleGeneratorKey。

  5. 键入并确认密码,再单击**“确定”**。

    在生成解决方案时,将使用密钥文件对程序集进行签名。

  6. 在**“文件”菜单上,单击“全部保存”**。

  7. 在**“生成”菜单上,单击“生成解决方案”**。

    现在已经创建了一个自定义数据生成器。

注册生成器程序集

在对程序集进行签名和编译后,下一步是收集项目中生成的程序集信息(包括版本、区域性和 PublicKeyToken),以便于注册生成器程序集。

收集程序集信息

  1. 在**“视图”菜单上,单击“其他窗口”,然后单击“命令窗口”打开“命令”**窗口。

  2. 在**“命令”**窗口中,键入以下代码。 将 FilePath 替换为已编译的 .dll 文件的路径和文件名。 在路径和文件名的两侧加双引号。

    提示

    默认情况下,已编译的 .dll 文件的路径为 SampleGenerator\bin\Debug。

    ? System.Reflection.Assembly.LoadFrom(@"<FilePath>").FullName
    
  3. 按 Enter。 此时该行应类似于以下内容,其中含有您的特定 PublicKeyToken:

    " SampleGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nnnnnnnnnnnnnnnn"
    

    记下或复制此程序集信息;下一过程中将使用这些信息。

接下来,将使用上一过程中收集的程序集信息创建 XML 文件。

创建 XML 文件

  1. 在**“解决方案资源管理器”**中,选择 SampleGenerator 项目。

  2. 在**“项目”菜单上选择“添加新项”**。

  3. 在**“模板”窗格中,找到并选择“XML 文件”**项。

  4. 在**“名称”文本框中,键入 SampleGenerator.Extensions.xml,然后单击“添加”**按钮。

    此时 SampleGenerator.Extensions.xml 文件将添加到**“解决方案资源管理器”**的项目中。

    提示

    必须使用 dll 的名称(在此例中为“SampleGenerator”后跟“.Extensions.xml”),程序集才能正确注册。

  5. 打开 SampleGenerator.Extensions.xml 文件,将其更新以匹配以下 XML。 替换上一过程中检索的程序集的版本、区域性和 PublicKeyToken。

    提示

    扩展类型必须使用类的完全限定名。 在此例中,扩展类型为“SampleGenerator.AddressGenerator”。

    <?xml version="1.0" encoding="utf-8"?>
    <extensions assembly="" version="1" xmlns="urn:Microsoft.Data.Schema.Extensions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:Microsoft.Data.Schema.Extensions Microsoft.Data.Schema.Extensions.xsd">
     
    <extension type="SampleGenerator.AddressGenerator" assembly="SampleGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nnnnnnnnnnnnnnnn" enabled="true"/>
     
    </extensions>
     
    
  6. 在**“文件”菜单上,单击“全部保存”**。

接下来,将程序集和 XML 文件复制到 Extensions 目录。 Visual Studio 高级专业版启动时将会标识 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions 目录和子目录中的任何扩展,并注册这些扩展以便在会话中使用。

将程序集和 XML 文件复制到 Extensions 目录并将其注册

  1. 在 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\ 目录中,创建一个名为 CustomGenerators 的文件夹。

  2. 将 SampleGenerator.dll 程序集文件从 项目文件夹\SampleGenerator\SampleGenerator\bin\Debug\ 目录复制到已创建的 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\ CustomGenerators 文件夹。

  3. 将 SampleGenerator.Extensions.xml 文件从 项目文件夹\SampleGenerator\SampleGenerator\ 目录复制到已创建的 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\ CustomGenerators 目录。

    提示

    最佳做法是将扩展程序集放在 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions 目录下的文件夹中。 此策略将帮助您标识随产品包括了哪些扩展,以及哪些扩展是您自定义创建的。 您还应考虑将扩展组织到特定于类别的文件夹中。

测试地址生成器

现在您已创建地址数据生成器,接下来您必须启动 Visual Studio 的新实例。 Visual Studio 在启动时将注册已添加到 %Program Files%\Microsoft Visual Studio 10.0\VSTSDB\Extensions\CustomGenerators 目录中的 SampleGenerator 程序集。 然后,您将创建可在其中验证地址数据生成器是否正常工作的数据库项目。

创建数据库项目

  1. 启动 Visual Studio 的新实例,这将识别 SampleGenerator.dll 程序集并对其进行注册。

  2. 在**“文件”菜单上指向“新建”,再单击“项目”**。

    此时将出现**“新建项目”**对话框。

  3. 在**“已安装的模板”下,展开“数据库”节点,然后单击“SQL Server”**节点。

  4. 在模板列表中单击**“SQL Server 2008 数据库项目”**。

  5. 在**“名称”**中,键入 SampleGeneratorDB。

    提示

    如果您已完成演练:为 CHECK 约束创建自定义数据生成器中的所有步骤,则您已创建 SampleGeneratorDB 项目,可以转至步骤 9。

  6. 选中**“创建解决方案的目录”**复选框。

  7. 接受**“位置”“解决方案名称”“添加到源代码管理”的默认值,然后单击“确定”**。

  8. 单击**“确定”**。

    新数据库项目“SampleGeneratorDB”将出现在**“解决方案资源管理器”**中。

  9. 在**“视图”菜单上,单击“数据库架构视图”**。

    如果**“架构视图”**尚未显示,此时将显示该视图。

接下来,您将向项目添加一个简单的表,其中包含一个 varchar SQL 类型的列。

向数据库项目中添加表

  1. 在**“架构视图”中,依次展开“SampleGeneratorDB”“架构”“dbo”节点,然后单击“表”**节点。

  2. 在**“项目”菜单上,单击“添加新项”**。

    提示

    也可以在“架构视图”中右击“SampleGeneratorDB”项目,指向“添加”,然后单击“表”

  3. 在**“模板”中,单击“表”**。

    提示

    “类别”列表中,可以单击“表和视图”以更容易地找到表的模板。

  4. 在**“名称”**中,键入“Addresses”作为要指定给新表的名称。

  5. 单击**“添加”**将该表添加到数据库项目中。

    **“解决方案资源管理器”**会在数据库项目中显示新表的文件。 **“架构视图”**会显示新表对象。 此时将出现 Transact-SQL 编辑器,其中显示新表的定义。

  6. 在 Transact-SQL 编辑器中,修改表定义以匹配以下示例:

    CREATE TABLE [dbo].[Addresses]
    (
    address varchar(100)
    )
    
  7. 在**“文件”菜单上,单击“保存 Addresses.table.sql”**。

在准备好表后,您可以配置数据库以供部署。

配置项目部署设置

  1. 在**“解决方案资源管理器”**中,单击“SampleGeneratorDB”项目(而非同名的解决方案)。

  2. 在**“项目”菜单上,单击“SampleGeneratorDB 属性”**。

    将显示项目的“属性”窗口。

    提示

    还可以在“解决方案资源管理器”中右击“SampleGeneratorDB”,然后单击“属性”

  3. 单击**“部署”**选项卡。

  4. 在**“部署操作”中,单击“创建部署脚本(.sql)并部署到数据库”**。

  5. 单击**“编辑”**按钮指定目标连接。

  6. 指定相应信息,以连接到要向其部署 SampleGeneratorDB 数据库的数据库服务器。

  7. 在**“选择或输入一个数据库名”**中,键入 SampleGeneratorDB。

  8. 单击**“确定”**。

    将用连接字符串填充**“目标连接”。 注意,“目标数据库名称”**设置为“SampleGeneratorDB”。

  9. 接受其他选项的默认值。

  10. 在**“文件”菜单上,单击“保存选定项”**。

    将保存该项目的生成设置。

接下来,您将生成数据库项目。

生成数据库项目

  • 在**“生成”菜单上,单击“生成解决方案”**。

    即会生成数据库项目。 如果成功,则会在状态栏中显示“生成成功”消息,并会在**“输出”**窗口中显示生成结果。

接下来将部署数据库项目。

将数据库项目部署到数据库服务器

  1. 在**“解决方案资源管理器”**中,单击“SampleGeneratorDB”项目(而非同名的解决方案)。

  2. 在**“生成”菜单上,单击“部署 SampleGeneratorDB”**。

    将使用在生成配置中指定的连接来部署数据库项目。 随后会在状态栏和**“输出”**窗口中显示“部署已成功”消息。

创建和配置数据生成计划

接下来将创建数据生成计划。 数据生成计划包含有关要用数据填充哪些表和列的信息。 有关更多信息,请参见如何:创建数据生成计划

创建和配置数据生成计划

  1. 在**“解决方案资源管理器”中,选择“数据生成计划”**节点。

  2. 在**“项目”菜单上,单击“添加新项”**。

  3. 在**“类别”窗格中,单击“数据生成计划”**。

  4. 在**“模板”窗格中,单击“数据生成计划”**。

  5. 在**“名称”**文本框中键入 SampleGenerator.dgen。

  6. 单击**“添加”**。

    即会创建数据生成计划。 该数据生成计划将出现。

    数据生成计划窗口按横向分为两个窗格。 上面的窗格将会列出在数据库项目架构中定义的表,在此例中为 dbo.Addresses 表。 下面的窗格将会显示上面的窗格中突出显示的表的列详细信息,在此例中为地址列。

    提示

    如果“数据生成预览”窗口尚未打开,则可以通过以下操作将其打开:打开“数据”菜单,指向“数据生成器”,然后单击“预览数据生成”。 默认情况下,“数据生成预览”窗口将作为一个选项卡停靠在数据生成计划窗口的底部。 若要展开视图,请单击窗口,然后单击“窗口”菜单上的“选项卡式文档”。 也可以右击标题栏,然后单击“以选项卡式文档停靠”

  7. 在 SampleGenerator.dgen 设计器中,确认已选择“dbo.Addresses”表和“address”(地址)列。

  8. 在 SampleGenerator.dgen 设计器中,选择“address”(地址)列并单击**“生成器”**下拉列表以选择 AddressGenerator。

    此时已正确配置自定义地址生成器。

  9. 在**“文件”菜单上,单击“全部保存”**。

运行数据生成计划以生成地址数据

最后,您将运行数据生成计划,并查看使用中的自定义地址数据生成器。

运行生成数据的计划

  1. 在**“解决方案资源管理器”**中,单击“SampleGenerator.dgen”。

    提示

    数据生成计划也必须打开。 如果计划未打开,请先将其打开。

  2. 在**“数据”菜单上,指向“数据生成器”,然后单击“生成数据”**。

    将出现**“连接到数据库”**对话框。

  3. 在**“数据生成连接信息”列表中,单击“SampleGeneratorDB”数据库,然后单击“确定”**。

  4. 提示在插入新行之前清除表内容时,单击**“是”**。

    将生成数据。 在“填充”窗口中,将用数据生成的状态更新状态列。 状态栏汇总了所有表的数据生成。

  5. (可选)使用其他工具登录数据库。 可以将 Visual Studio 高级专业版中提供的 Transact-SQL 编辑器用于此步骤。 有关更多信息,请参见 Microsoft 网站上的 Editing Database Scripts and Objects with the Transact-SQL Editor(使用 Transact-SQL 编辑器编辑数据库脚本和对象)。

  6. 通过运行以下查询查看新数据:

    use SampleGeneratorDB
    
    select * from dbo.Addresses
    

    **“结果”**选项卡应显示包含随机的省/市/自治区值和邮政编码值的地址。

后续步骤

Visual Studio 高级专业版和 Visual Studio 旗舰版包含 DateTime 生成器,通过使用该生成器的 Min 和 Max 属性,可将该生成器用于具有一个要求日期位于某个范围内的 CHECK 约束的列。 在演练:为 CHECK 约束创建自定义数据生成器中,您将为具有一个 CHECK 约束(它要求日期位于两个不同的范围之一内)的列创建自定义数据生成器。

请参见

任务

如何:注册和管理功能扩展

如何:将输入属性添加到数据生成器

如何:将输出属性添加到数据生成器

如何:创建自定义数据生成器

演练:创建和运行数据生成计划

参考

Microsoft.Data.Schema.Tools.DataGenerator

概念

扩展 Visual Studio 的数据库功能

数据生成器扩展性概述

其他资源

Editing Database Scripts and Objects with the Transact-SQL Editor

管理程序集签名和清单签名