zoukankan      html  css  js  c++  java
  • CodeSmith NetTier模板生成的代码框架用法 (转)

     
    1.1. 概述:
    使用NetTier模板生成的.net代码,包括完整的数据层,使用的技术是微软的
    EnterpriseLibrary1.1版本,对应每张表都生成相对应的增删改查函数和存储过程,在查询中支
    持多字段查询和翻页。数据层为工厂模型,只要调用DataRepository 类即可获取相应表的接
    口实例,然后可以对改表进行操作了。对于多表关联操作,在父表中可以获取子集的查询记
    录,保存在IList 容器里面,对于子表,提供父表的对象实例。对于数据库的操作提供事务功
    能。对于更加复杂的操作,直接提供EnterpriseLibrary的数据库操作实例,直接进行操作。
    特征:
    1、 生成vs.net工程和解决方案;
    2、 集成EnterpriseLibrary1.1版本,对于数据库链接可以直接使用EnterpriseLibrary的配置文
    件;
    3、 数据表和实体的映射关系是1:1的,每张表都有一个实体生成,在实体里面对应了每个
    字段,实体类是序列化的,有trigger事件,支持枚举类型的字段;
    4、 对于表和视图生成的实体的操作包括:基本的CRUD操作:UPDATE, DELETE, INSERT,
    SELECT ALL, PAGED SELECT, FIND;支持主键、外键、多表关联、排序、分页、sql
    语句、视图查询;
    5、 获取强类型的数据集存储在Ilist或者Vlist里面,可以绑定到DataGrid、GridView或
    者其他的页面控件中,支持表格排序;
    6、 生成webservice 服务进行数据分发;
    7、 创建存储过程脚本,而且自动安装到数据库服务器上面;
    8、 生成nant的完整的build.xml 文件,可以自动编译、测试代码,生成chm 格式的api
    文档;
    9、 根据数据库生成完整的数据验证规则,包括一个管理规则的框架;
    10、 每个表都有一个实体类,你可以在你的客户代码里面继承,然后增加自己的处理方
    法;
    11、 生成数据源可以让你你无需再去处理数据源的问题了;
    12、 创建全套的web admin用户控件,你可以对数据库进行web管理;
    13、 完整的nunit测试;
    14、 完整的注释,符合微软的命名规则;
    15、 nettiers 模板是免费开源的。
    1.2. 框架结构:
    数据逻辑包括客户业务逻辑组件、数据接口逻辑组件(持久层逻辑),整个设计建筑在el
    上面。
    下面以northwind数据库的单表employee为例进行讲解。
    Employee数据表结构:
    生成的OO 结构:
    接口统一的调用DataRepository 获取各功能块的provider,然后进行单表的增删改查操
    作,如果需要更加复杂的业务逻辑,比如要用到事务来同时处理几个表,那么需要另外写业务
    逻辑代码了,这些逻辑层代码可以放在bl 层里面。值得一提的是,现在在bl 层里面生成的代
    码,只有最基本和通用的业务逻辑,只生成了单表数据的实体类VO、单表数据各字段的处理
    和数据集合的排序、检索等处理。
    EmployeesCollection
    EmployeesCollectionBase
    Employees
    EmployeesBase EmployeesVO
    在DataRepository 里面获取各功能模块的provider的方法是static 方法,得到的是各
    个sqlprovider 的实例,而提供给外界使用的是其对应的抽象类定义的方法。
    实例的调用顺序是:
    :
    DataRepository
    :
    SqlDataProvider
    :
    SqlEmployeesProviderBase
    1: EmployeesProvider
    2: GetAll
    3: GetByEmployeeID
    分析DataRepository.EmployeesProvider.GetAll()的操作:实例化的顺序是
    DataRespository 类里面维护了一个全局的变量Current,这个Current实际上是
    SqlDataProvider 的实例,而Current是DataProviderBase 类型,关系为:
    DataProviderBase
    SqlDataProvider
    (from sqlclient)
    在DataRepository 中获取EmployeesProvider的时候,实际上是调用了
    SqlDataProvider 里面的方法EmployeesProvider(),new 了一个SqlEmployeesProvider 实
    例,而这个实例中所有的方法的实现在SqlEmployeesProviderBase类中实现的,因为
    SqlEmployeesProvider继承了SqlEmployeesProviderBase类,这个类相当于是dao 层,直接进行
    数据库操作。
    SqlEmployeesProviderBase
    EmployeesProviderBase
    (from base)
    SqlEmployeesProvider
    在生成各个sqlprovider 实例的时候,需要先实例化SqlDataProvider,这个用的是
    Activator 类根据配置文件提供的这个类的名字生成的,nettier为了做到对不同数据库的支
    持,提供了一个配置文件nettiersconfigdata.config 和读取这个配置文件的dll:
    NetTiers.Configuration.dll。
    Activator 类可以动态构造对象,有点像Java里面的
    Class.forName(ClassName).newInstance()语句,因为用Activator 类构造对象,其类名在
    编译时可以不确定,所以可以用来做插件的接口,做出Winamp 那种可以外加DLL 插件的程序
    来。
    1.3. 调用接口的方法:
    1.3.1. 获取所有数据
    获取所有的Employee数据,按照LastName字段进行排序:
    using Northwind.DataAccessLayer;
    // Get all the employee, sort it on the LastName and print them out
    TList<Employees> employees = DataRepository.EmployeeProvider.GetAll();
    employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
    foreach(Employee employee in employees)
    {
    Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
    }
    1.3.2. 新增数据
    创建一个新的employee 并且保存
    using Northwind.DataAccessLayer;
    // Create a new record and save
    Employee employee = new Employee();
    employee.FirstName = "John";employee.LastName = "Doe";
    employee.BirthDate = DateTime.Now;employee.Address = "10 , fake street";
    employee.City = "Metroplolis";employee.Country = "USA";
    employee.HireDate = DateTime.Now;
    employee.HomePhone = "0123456789";
    employee.Notes = "This is a fake employee";
    employee.Title = "M";
    employee.TitleOfCourtesy = "Dear";
    employee.PostalCode = "5556";
    employee.Region = "New-York";
    DataRepository.EmployeeProvider.Insert(employee);
    //look, new id already populated
    Console.WriteLine("New Employee ID" + employee.EmployeeId);
    1.3.3. 修改数据
    按照下标获取数据并且修改数据;
    using Northwind.DataAccessLayer;
    // Select by Index and Update
    TList<Employees> employees =
    DataRepository.EmployeeProvider.GetByLastName("Doe");
    if (employees.Count == 1)
    {
    employees[0].Notes = "This is a modified fake employee";
    DataRepository.EmployeeProvider.Save(employees[0]);
    Console.Write(employees[0]);
    }
    1.3.4. 删除数据
    通过主键查询数据并且删除
    using Northwind.DataAccessLayer;
    // Select by primary key and Delete
    // (Demonstrate that insert, update, delete methods can also take collection
    as parameter)
    Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
    DataRepository.EmployeeProvider.Delete(employees);
    1.3.5. 事务控制
    事务控制实例,可以用事务控制插入、修改、删除的操作,保证全部成功或者失败回滚;
    using Northwind.DataAccessLayer;
    // The SqlClient can work with transactions.
    // Also show the Save method, wich encapsulate the use of Insert, Update and
    Delete methods.
    TransactionManager transaction = DataRepository.CreateTransaction();
    transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
    try
    {
    // Insert
    Employee employee = new Employee();
    employee.FirstName = "John";
    employee.LastName = "Doe";
    employee.BirthDate = DateTime.Now;
    employee.Address = "10 , fake street";
    employee.City = "Metroplolis";
    employee.Country = "USA";
    employee.HireDate = DateTime.Now;
    employee.HomePhone = "0123456789";
    mployee.Notes = "This is a fake employee";
    employee.Title = "M";
    employee.TitleOfCourtesy = "Doctor";
    employee.PostalCode = "5556";
    employee.Region = "New-York";
    DataRepository.EmployeeProvider.Save(transaction, employee);
    // modify the employee instance
    employee.Notes = "This is a modified fake employee";
    // Update
    DataRepository.EmployeeProvider.Save(transaction, employee);
    transaction.Commit();
    Console.WriteLine("ok");
    }
    catch(Exception ex)
    {
    try { transaction.Rollback();} catch(){}
    Console.WriteLine("nok : {0}", ex);
    }
    1.3.6. 关联保存
    深度保存,可以同时保存父对象和子集
    /*
    DeepSave helper method can help you to save an object and its children in
    one call.
    */
    using Northwind.DataAccessLayer;
    Order order = Order.CreateOrder("ALFKI", 1, DateTime.Now, DateTime.Now,
    DateTime.Now, 1, 0.1m, "ship name", "ship address" , "paris", "idf", "75000",
    "france");
    order.OrderDetailCollection.Add(order.OrderID, 1, 15.6m, 10, 0.02f);
    order.OrderDetailCollection.Add(order.OrderID, 2, 122.6m, 43, 0.03f);
    DataRepository.OrderProvider.DeepSave(order);
    Console.WriteLine("new order saved: orderId is: " + order.OrderID.ToString());
    1.3.7. 多数据库支持
    同时支持多个不同的数据库进行操作,在el 配置文件中配置不同的数据库连接或者在代
    码中动态生成不同的数据库连接,达到同时使用不同类型数据库的目的。
    /*
    You can configure multiple data provider in the configuration console, and
    write code to acces a specific one, instead of the default.
    */
    using Northwind.DataAccessLayer;
    SqlDataProvider myRepository = DataRepository.Providers["my second data
    provider"] as Northwind.DataAccessLayer.SqlClient.SqlDataProvider;
    this.listBox1.DataSource = myRepository.ProductProvider.GetAll();
    this.listBox1.DisplayMember = "ProductName";
    this.listBox1.ValueMember = "ProductID";
    //Or if you can't have it pre-configured, you can change the connection
    string at runtime.
    using Northwind.DataAccessLayer;
    //New syntax using a declared connection string:
    TList<Products> list =
    DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvide
    r.GetAll();
    //New syntax using a dynamic connection string:
    DataRepository.AddConnection("DynamicConnectionString", "Data
    Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
    TList<Products< list =
    DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.Ge
    tAll();
    this.listBox1.DataSource = list;
    this.listBox1.DisplayMember = "ProductName";
    this.listBox1.ValueMember = "ProductID";
    1.4. 配置nettiers模板
    1.4.1. Datasource目录:
    SourceDatabase 数据库名字和连接参数,在codesmith explore中有配置界面弹出
    SourceTables 在数据表里面需要实体化的表
    EntireDatabase 明确在数据库中需要实体化的表,这个设置将取代SourceTables 的设置
    1.4.2. General 目录
    OuputDirectory 输出目录,在codesmith explore里面有配置界面弹出
    BusinessLogicLayerFolderName 逻辑层子目录名,推荐置空
    DataAccessLayerFolderName 数据层子目录名,推荐值:DataAccessLayer
    SqlFolderName 存储过程脚本目录名,推荐:SQL
    NameSpace 项目的命名空间,名称和目录同。
    GenerateUnitTest 声明生成nunit测试项目名
    VsNetIntegration 声明是整个的生成一个工程还是按层分开生成工程
    VsNetVersion Vs.net的版本
    1.4.3. Webservice参数
    GenerateWebService 声明是否生成webservice服务
    WebServiceOutputPath Webservice的生成文件路径
    WebServiceUrl 数据层子目录名,推荐值:DataAccessLayer
    SqlFolderName 指向WebServiceOutputPath 的url
    配置完成后可以保存为配置文件,下次只需要载入即可。
    新增了web层的模板,叫weblayer,实现单表的增删改查;
    给一个配置好的例子,对sqlserver2000的数据库northwind的配置例子,见netier目录下面
    property.xml文件,可以直接载入然后生成对应的代码,生成的是完整的工程,可以直接编译
    运行。  
    1.1. 概述:
    使用NetTier模板生成的.net代码,包括完整的数据层,使用的技术是微软的
    EnterpriseLibrary1.1版本,对应每张表都生成相对应的增删改查函数和存储过程,在查询中支
    持多字段查询和翻页。数据层为工厂模型,只要调用DataRepository 类即可获取相应表的接
    口实例,然后可以对改表进行操作了。对于多表关联操作,在父表中可以获取子集的查询记
    录,保存在IList 容器里面,对于子表,提供父表的对象实例。对于数据库的操作提供事务功
    能。对于更加复杂的操作,直接提供EnterpriseLibrary的数据库操作实例,直接进行操作。
    特征:
    1、 生成vs.net工程和解决方案;
    2、 集成EnterpriseLibrary1.1版本,对于数据库链接可以直接使用EnterpriseLibrary的配置文
    件;
    3、 数据表和实体的映射关系是1:1的,每张表都有一个实体生成,在实体里面对应了每个
    字段,实体类是序列化的,有trigger事件,支持枚举类型的字段;
    4、 对于表和视图生成的实体的操作包括:基本的CRUD操作:UPDATE, DELETE, INSERT,
    SELECT ALL, PAGED SELECT, FIND;支持主键、外键、多表关联、排序、分页、sql
    语句、视图查询;
    5、 获取强类型的数据集存储在Ilist或者Vlist里面,可以绑定到DataGrid、GridView或
    者其他的页面控件中,支持表格排序;
    6、 生成webservice 服务进行数据分发;
    7、 创建存储过程脚本,而且自动安装到数据库服务器上面;
    8、 生成nant的完整的build.xml 文件,可以自动编译、测试代码,生成chm 格式的api
    文档;
    9、 根据数据库生成完整的数据验证规则,包括一个管理规则的框架;
    10、 每个表都有一个实体类,你可以在你的客户代码里面继承,然后增加自己的处理方
    法;
    11、 生成数据源可以让你你无需再去处理数据源的问题了;
    12、 创建全套的web admin用户控件,你可以对数据库进行web管理;
    13、 完整的nunit测试;
    14、 完整的注释,符合微软的命名规则;
    15、 nettiers 模板是免费开源的。
    1.2. 框架结构:
    数据逻辑包括客户业务逻辑组件、数据接口逻辑组件(持久层逻辑),整个设计建筑在el
    上面。
    下面以northwind数据库的单表employee为例进行讲解。
    Employee数据表结构:
    生成的OO 结构:
    接口统一的调用DataRepository 获取各功能块的provider,然后进行单表的增删改查操
    作,如果需要更加复杂的业务逻辑,比如要用到事务来同时处理几个表,那么需要另外写业务
    逻辑代码了,这些逻辑层代码可以放在bl 层里面。值得一提的是,现在在bl 层里面生成的代
    码,只有最基本和通用的业务逻辑,只生成了单表数据的实体类VO、单表数据各字段的处理
    和数据集合的排序、检索等处理。
    EmployeesCollection
    EmployeesCollectionBase
    Employees
    EmployeesBase EmployeesVO
    在DataRepository 里面获取各功能模块的provider的方法是static 方法,得到的是各
    个sqlprovider 的实例,而提供给外界使用的是其对应的抽象类定义的方法。
    实例的调用顺序是:
    :
    DataRepository
    :
    SqlDataProvider
    :
    SqlEmployeesProviderBase
    1: EmployeesProvider
    2: GetAll
    3: GetByEmployeeID
    分析DataRepository.EmployeesProvider.GetAll()的操作:实例化的顺序是
    DataRespository 类里面维护了一个全局的变量Current,这个Current实际上是
    SqlDataProvider 的实例,而Current是DataProviderBase 类型,关系为:
    DataProviderBase
    SqlDataProvider
    (from sqlclient)
    在DataRepository 中获取EmployeesProvider的时候,实际上是调用了
    SqlDataProvider 里面的方法EmployeesProvider(),new 了一个SqlEmployeesProvider 实
    例,而这个实例中所有的方法的实现在SqlEmployeesProviderBase类中实现的,因为
    SqlEmployeesProvider继承了SqlEmployeesProviderBase类,这个类相当于是dao 层,直接进行
    数据库操作。
    SqlEmployeesProviderBase
    EmployeesProviderBase
    (from base)
    SqlEmployeesProvider
    在生成各个sqlprovider 实例的时候,需要先实例化SqlDataProvider,这个用的是
    Activator 类根据配置文件提供的这个类的名字生成的,nettier为了做到对不同数据库的支
    持,提供了一个配置文件nettiersconfigdata.config 和读取这个配置文件的dll:
    NetTiers.Configuration.dll。
    Activator 类可以动态构造对象,有点像Java里面的
    Class.forName(ClassName).newInstance()语句,因为用Activator 类构造对象,其类名在
    编译时可以不确定,所以可以用来做插件的接口,做出Winamp 那种可以外加DLL 插件的程序
    来。
    1.3. 调用接口的方法:
    1.3.1. 获取所有数据
    获取所有的Employee数据,按照LastName字段进行排序:
    using Northwind.DataAccessLayer;
    // Get all the employee, sort it on the LastName and print them out
    TList<Employees> employees = DataRepository.EmployeeProvider.GetAll();
    employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
    foreach(Employee employee in employees)
    {
    Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
    }
    1.3.2. 新增数据
    创建一个新的employee 并且保存
    using Northwind.DataAccessLayer;
    // Create a new record and save
    Employee employee = new Employee();
    employee.FirstName = "John";employee.LastName = "Doe";
    employee.BirthDate = DateTime.Now;employee.Address = "10 , fake street";
    employee.City = "Metroplolis";employee.Country = "USA";
    employee.HireDate = DateTime.Now;
    employee.HomePhone = "0123456789";
    employee.Notes = "This is a fake employee";
    employee.Title = "M";
    employee.TitleOfCourtesy = "Dear";
    employee.PostalCode = "5556";
    employee.Region = "New-York";
    DataRepository.EmployeeProvider.Insert(employee);
    //look, new id already populated
    Console.WriteLine("New Employee ID" + employee.EmployeeId);
    1.3.3. 修改数据
    按照下标获取数据并且修改数据;
    using Northwind.DataAccessLayer;
    // Select by Index and Update
    TList<Employees> employees =
    DataRepository.EmployeeProvider.GetByLastName("Doe");
    if (employees.Count == 1)
    {
    employees[0].Notes = "This is a modified fake employee";
    DataRepository.EmployeeProvider.Save(employees[0]);
    Console.Write(employees[0]);
    }
    1.3.4. 删除数据
    通过主键查询数据并且删除
    using Northwind.DataAccessLayer;
    // Select by primary key and Delete
    // (Demonstrate that insert, update, delete methods can also take collection
    as parameter)
    Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
    DataRepository.EmployeeProvider.Delete(employees);
    1.3.5. 事务控制
    事务控制实例,可以用事务控制插入、修改、删除的操作,保证全部成功或者失败回滚;
    using Northwind.DataAccessLayer;
    // The SqlClient can work with transactions.
    // Also show the Save method, wich encapsulate the use of Insert, Update and
    Delete methods.
    TransactionManager transaction = DataRepository.CreateTransaction();
    transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
    try
    {
    // Insert
    Employee employee = new Employee();
    employee.FirstName = "John";
    employee.LastName = "Doe";
    employee.BirthDate = DateTime.Now;
    employee.Address = "10 , fake street";
    employee.City = "Metroplolis";
    employee.Country = "USA";
    employee.HireDate = DateTime.Now;
    employee.HomePhone = "0123456789";
    mployee.Notes = "This is a fake employee";
    employee.Title = "M";
    employee.TitleOfCourtesy = "Doctor";
    employee.PostalCode = "5556";
    employee.Region = "New-York";
    DataRepository.EmployeeProvider.Save(transaction, employee);
    // modify the employee instance
    employee.Notes = "This is a modified fake employee";
    // Update
    DataRepository.EmployeeProvider.Save(transaction, employee);
    transaction.Commit();
    Console.WriteLine("ok");
    }
    catch(Exception ex)
    {
    try { transaction.Rollback();} catch(){}
    Console.WriteLine("nok : {0}", ex);
    }
    1.3.6. 关联保存
    深度保存,可以同时保存父对象和子集
    /*
    DeepSave helper method can help you to save an object and its children in
    one call.
    */
    using Northwind.DataAccessLayer;
    Order order = Order.CreateOrder("ALFKI", 1, DateTime.Now, DateTime.Now,
    DateTime.Now, 1, 0.1m, "ship name", "ship address" , "paris", "idf", "75000",
    "france");
    order.OrderDetailCollection.Add(order.OrderID, 1, 15.6m, 10, 0.02f);
    order.OrderDetailCollection.Add(order.OrderID, 2, 122.6m, 43, 0.03f);
    DataRepository.OrderProvider.DeepSave(order);
    Console.WriteLine("new order saved: orderId is: " + order.OrderID.ToString());
    1.3.7. 多数据库支持
    同时支持多个不同的数据库进行操作,在el 配置文件中配置不同的数据库连接或者在代
    码中动态生成不同的数据库连接,达到同时使用不同类型数据库的目的。
    /*
    You can configure multiple data provider in the configuration console, and
    write code to acces a specific one, instead of the default.
    */
    using Northwind.DataAccessLayer;
    SqlDataProvider myRepository = DataRepository.Providers["my second data
    provider"] as Northwind.DataAccessLayer.SqlClient.SqlDataProvider;
    this.listBox1.DataSource = myRepository.ProductProvider.GetAll();
    this.listBox1.DisplayMember = "ProductName";
    this.listBox1.ValueMember = "ProductID";
    //Or if you can't have it pre-configured, you can change the connection
    string at runtime.
    using Northwind.DataAccessLayer;
    //New syntax using a declared connection string:
    TList<Products> list =
    DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvide
    r.GetAll();
    //New syntax using a dynamic connection string:
    DataRepository.AddConnection("DynamicConnectionString", "Data
    Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
    TList<Products< list =
    DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.Ge
    tAll();
    this.listBox1.DataSource = list;
    this.listBox1.DisplayMember = "ProductName";
    this.listBox1.ValueMember = "ProductID";
    1.4. 配置nettiers模板
    1.4.1. Datasource目录:
    SourceDatabase 数据库名字和连接参数,在codesmith explore中有配置界面弹出
    SourceTables 在数据表里面需要实体化的表
    EntireDatabase 明确在数据库中需要实体化的表,这个设置将取代SourceTables 的设置
    1.4.2. General 目录
    OuputDirectory 输出目录,在codesmith explore里面有配置界面弹出
    BusinessLogicLayerFolderName 逻辑层子目录名,推荐置空
    DataAccessLayerFolderName 数据层子目录名,推荐值:DataAccessLayer
    SqlFolderName 存储过程脚本目录名,推荐:SQL
    NameSpace 项目的命名空间,名称和目录同。
    GenerateUnitTest 声明生成nunit测试项目名
    VsNetIntegration 声明是整个的生成一个工程还是按层分开生成工程
    VsNetVersion Vs.net的版本
    1.4.3. Webservice参数
    GenerateWebService 声明是否生成webservice服务
    WebServiceOutputPath Webservice的生成文件路径
    WebServiceUrl 数据层子目录名,推荐值:DataAccessLayer
    SqlFolderName 指向WebServiceOutputPath 的url
    配置完成后可以保存为配置文件,下次只需要载入即可。
    新增了web层的模板,叫weblayer,实现单表的增删改查;
    给一个配置好的例子,对sqlserver2000的数据库northwind的配置例子,见netier目录下面
    property.xml文件,可以直接载入然后生成对应的代码,生成的是完整的工程,可以直接编译
    运行。
      

  • 相关阅读:
    字串变换
    重建道路
    poj3278 Catch That Cow
    机器人搬重物
    [HNOI2004]打鼹鼠
    曼哈顿距离
    邮票面值设计
    poj1101 The Game
    解决了一个堆破坏问题
    模型资源从无到有一条龙式体验
  • 原文地址:https://www.cnblogs.com/SlashOut/p/833840.html
Copyright © 2011-2022 走看看