[译]Netties使用说明
2006-09-23 12:47
253 查看
目录
前言
1. 概念
2. Northwind例子
简单模型
代码示例
3. 配置
4. 高级读取和保存
5. 增加基于自定义存储过程的数据存取方法
概述
示例
6. NAnt文件
7. 模板参数
8. 单元测试
9. 建议
数据库设计向导
10. 版本历史
v0.9-Childebert
v1.0-Clotaire
v1.1-Caribert
11. 项目信息
简述
贡献人
前言
.netTiers是针对对象关系映射的一个CodeSmith模板,它采用现成的SQL Server数据库,并为你的应用程序自动生成个性化的DataTiers应用程序块。
主要的特性有:
产生现成的Visual Studio项目和解决方案
完全集成企业库应用程序块框架,用自生插件封装,因而你可以直接用企业库配置控制台来配置你的应用程序
一对一地产生业务对象(实体),一个实体对应一个表,一个属性对应一列
可序列化
触发实体事件
实现了接口IEntity,包含了表中出现的每一个列
对枚举类型及其产生的特别支持
为数据表和视图产生数据访问层组件,来完成以下数据库操作:
基本的CRUD:UPDATE,DELETE,INSERT,SELECT ALL,PAGED SELECT,FIND
按主键查询
按外键查询
按索引查询(非主键和外键)
按连接查询(多对多关系)
支持由命名规则确定的查询产生的用户自定义方法。你也可以从邮件中获取更多的信息
使用子查询和可选的嵌套来完成高级读取和保存
支持分页和排序的查询方法
支持SQL视图
可以选择存储过程或者使用嵌入XML查询文件的参数化SQL语句
使用TList<>和(或)VList为实体和库产生强类型的通用集合。
实现了BingdingList<T>,IBindingListView,IBindingList,IList,ICloneable,IListSource,ITypedList,IDisposable,IComponent,IRaiseITemChangedEvents,IDeserializationCallback等泛型和接口
可排序的,甚至不可排序
可以绑定任意的gridview,datagrid或者任何其他winform和asp.net控件
为分布式编程创建ASP.NET Webservice
创建存储过程脚本并且能自动的安装到服务器
创建完整的NAnt build文件来编译,测试和产生chm/html API文档
创建基于数据库方案的全套验证规则库,并且包括管理你的规则的完整框架
每个对象有其具体类及其继承的基类。这个具体的类一旦被产生,你可以在自己的代码里面使用。每个基类都是分布类型类,你可以毫无障碍地扩展其功能
创建一个EntityDataSource,你将不再被ObjectDataSource的缺点所困扰,.netTiers提供了先进的EntityDataSource,它关联数据仓库并创建100%公开的模型,没有任何后台代码
创建全套的web管理控件,你可以为你的数据库准确快速地建立一个web管理平台
Do I have to keep going, I mean come on, there are features out the wazzuua, download it today...
全套的NUnit测试
代码有详细的注解来描述数据表及其列的扩展属性,遵循微软命名规则
它是免费和开源的!你可以在我们的允许条款内随意的修改模板,捐献出来回馈社区(http://www.sourceforge.net/projects/nettiers)
第一章 概念
这个data tiers的概念包括自定义业务实体组件(数据本身)和数据访问逻辑组件(持久逻辑)两部分。设计的灵感来自于微软的patterns&practices向导Designing Data Tier Components and Passing Data Through Tiers:
第二章 Northwind示例
示例模型
为了阐明模板的原理,我们使用了Employee表:
表2.1. Employee表
产生的OO架构如下:
代码示例:
using Northwind.DataAccessLayer;
// 获取所有的employee,并以LastName升序排序输出
TList<Employees> employees = DataRepository.EmployeesProvider.GetAll();
employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
foreach(Employees employee in employees)
{
Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
}
using Northwind.DataAccessLayer;
// 创建并保存一条记录
Employees employee = new Employees();
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);
//看,新的ID已经增加
Console.WriteLine("New Employee ID" + employee.EmployeeID);
using Northwind.DataAccessLayer;
// 按主键查询和删除
// 示范insert,update,delete方法也可以采用collection作为参数
Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
DataRepository.EmployeesProvider.Delete(employees);
using Northwind.DataAccessLayer;
// SqlClient可以使用事务处理
// 显示封装了insert,update,delete方法的Save方法
TransactionManager transaction = DataRepository.CreateTransaction();
transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
try
{
// 新增
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);
// 修改employee实例
employee.Notes = "This is a modified fake employee";
// 更新
DataRepository.EmployeeProvider.Save(transaction, employee);
transaction.Commit();
Console.WriteLine("ok");
}
catch(Exception ex)
{
try { transaction.Rollback();} catch(){}
Console.WriteLine("nok : {0}", ex);
}
/*
DeepSave辅助方法能协助你以一次调用来保存对象及其成员
*/
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());
/*
你也可以在配置控制台配置多个数据提供者,用代码来使用其中不是默认的的一个
*/
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";
//要不然,如果你不能预先配置,你也可以在运行时改变连接字符串
using Northwind.DataAccessLayer;
//使用配置的其他连接字符串的新语法
TList<Products> list = DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvider.GetAll();
//使用动态的连接字符串的新语法
DataRepository.AddConnection("DynamicConnectionString", "Data Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
TList<Products> list = DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.GetAll();
this.listBox1.DataSource = list;
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
第三章 配置
以下是配置.netTiers组件的步骤,以Northwind数据库为例。
为了配置你的应用程序来使用.netTiers,你需要增加以下的节到你的App/Web config文件中。在.netTiers 2 Install and Configuration Document你能找到更多的信息。
1. 增加一个新的节到configSettings
<section name="netTiersService"
type="Northwind.DataAccessLayer.Bases.NetTiersServiceSection, Northwind.DataAccessLayer"
allowDefinition="MachineToApplication"
restartOnExternalChanges="true" />
2. 在ConnectionStrings节中增加一项
<connectionStrings>
<add name="netTiersConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=true;Connection Timeout=1;" />
</connectionStrings>
3. 增加netTierServie配置节到你的配置文件中。不使用的时候注释掉即可。
<netTiersService defaultProvider="SqlNetTiersProvider">
<providers>
<add
name="SqlNetTiersProvider"
type="Northwind.DataAccessLayer.SqlClient.SqlNetTiersProvider, Northwind.DataAccessLayer.SqlClient"
connectionStringName="netTiersConnectionString"
useStoredProcedure="false"
providerInvariantName="System.Data.SqlClient" />
</providers>
</netTiersService>
第四章 高级读取和保存
第五章 增加基于存储过程的数据访问方法
概述
你应该增加数据访问组件的新方法到具体的类中,而不是每一次产生类的时候重写基类,具体的类仅仅产生一次。这种解决方案是好的,但是目前有一些缺陷:
为了提供相同的功能你必须重载许多方法,而不是产生代码
可选的解决方法是:从你的存储过程产生方法。为了激活它,你需要设定“Include custom sql”选项为True。这样,你的存储过程名必须以“_TableName_”开始,后面接上你给方法取的名称。这个命名规范保证模板能检测到你的存储过程,从而为正确的数据类(xxTableNameRepository)创建方法。
示例
用一个例子作为解释,考虑Northwind数据库的Product数据表,假设我们需要查询库存在给出值以下的所有产品列表,那么首先我们创建以下存储过程:
-- Get the products that have less units in stock than the @UnitsInStock parameter.
CREATE PROCEDURE dbo._Products_GetWithStockBelow
@UnitsInStock smallint
AS
SELECT
[ProductID],
[ProductName],
[SupplierID],
[CategoryID],
[QuantityPerUnit],
[UnitPrice],
[UnitsInStock],
[UnitsOnOrder],
[ReorderLevel],
[Discontinued]
FROM
[dbo].[Products]
WHERE
[UnitsInStock] < @UnitsInStock
GO
之后我们运行产生器,将看到SqlClient的ProductRepository类的自定义方法(Custom Methods)如下:
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="start">Row number at which to start reading.</param>
/// <param name="pageLength">Number of rows to return.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(int start, int pageLength , System.Int16 UnitsInStock)
{
return GetWithStockBelow(this.transactionManager, this.connectionString, 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="transactionManager"><see cref="TransactionManager" /> object</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(TransactionManager transactionManager , System.Int16 UnitsInStock)
{
return GetWithStockBelow(transactionManager, string.Empty , 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(System.Int16 UnitsInStock)
{
return GetWithStockBelow(this.transactionManager, this.connectionString, 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="start">Row number at which to start reading.</param>
/// <param name="pageLength">Number of rows to return.</param>
/// <param name="transactionManager"><see cref="TransactionManager" /> object</param>
/// <param name="connectionString">Connection string to datasource.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
protected ProductCollection GetWithStockBelow(TransactionManager transactionManager, string connectionString, int start, int pageLength , System.Int16 UnitsInStock)
{
SqlDataReader reader;
if (transactionManager != null)
reader = SqlHelper.ExecuteReader(transactionManager.TransactionObject, "_Products_GetWithStockBelow", UnitsInStock);
else
reader = SqlHelper.ExecuteReader(connectionString, "_Products_GetWithStockBelow", UnitsInStock);
//Create Collection
ProductCollection rows = new ProductCollection();
Fill(reader, rows, start, pageLength);
reader.Close();
return rows;
}
正如你看到的,所有重载方法被产生,包括SqlClient和WebServiceClient版本并且支持参数和分页。
第六章 NAnt文件
模板将产生一个NAnt的Build文件。这里我不解释什么是NAnt了,你可以从nAnt homepage找到更多的信息。基本上,它是用于在没有visual studio的情况下从命令行编译程序,但是它又不仅仅局限于此,它也可以用于运行Nunit测试和建立NDoc文档。
第七章 模板参数
本模板在许多方面是可设定的:
DataSource 栏
SourceDatabase 你想创建应用程序块的数据库
SourceTables 你想包含到产生器内的数据表列表
EntireDatabase 指明是否所有数据表必须被包含,结果是它将覆盖SourceTables列表
General 栏
OuputDirectory 产生代码的输出路径
BusinessLogicLayerFolderName BLL(实体和实体关系)代码输出文件夹名,推荐为空
DataAccessLayerFolderName DAL(数据仓库)代码输出文件夹名,推荐为:DataAccessLayer
SqlFolderName 数据库存储过程脚本的输出文件夹名,推荐为:SQL
NameSpace 项目的根命名空间。DAL的输出文件夹名将作为DAL的命名空间(命名空间结构即为目录结构)
GenerateUnitTest 指明是否产生测试代码
VsNetIntegration 说明Visual Studio集成的类型:none,single project,separated project(BLL和DAL)
VsNetVersion 说明Visual Studio的版本
WebService参数
GenerateWebService 指明是否asp.net webservice及其对应的DAL必须产生
WebServiceOutputPath asp.net webservice的完整输出路径
WebServiceUrl WebService输出路径所对应的URL
(例如:http://localhost/Services/DatabaseNameRepository)
第八章 单元测试
本模板能可选地产生NUnit测试代码。目前为止,产生的代码包括:
Insert
Update
GetAll
Delete
DeepLoad
Serialization
第九章 建议
数据库设计指南
理想的情况下,为了模板最好的实现,你的数据库应该应用以下的规则:
表名是单一的并且使用Pascal命名方法
字段使用Pascal命名方法并且给出相应的描述
外键关联
要作为查询条件的一个字段或多个字段应该是表的索引
自定义的存储过程名应该以一个下划线开始,后面接表名
表名不要以“Collection”结尾
不要以“ListItem”作为表名
第十章 版本历史
v0.9 - Childebert
v1.0 - Clotaire
v1.1 - Caribert
第十一章 项目信息
描述
本项目是开源的,由sourceforge主持。你也可以通过搜索或者codesmith论坛来获取信息。模板最早是由Ryan Hurdon开发的,现在有John Roland维护。
(贡献人等信息略)
前言
1. 概念
2. Northwind例子
简单模型
代码示例
3. 配置
4. 高级读取和保存
5. 增加基于自定义存储过程的数据存取方法
概述
示例
6. NAnt文件
7. 模板参数
8. 单元测试
9. 建议
数据库设计向导
10. 版本历史
v0.9-Childebert
v1.0-Clotaire
v1.1-Caribert
11. 项目信息
简述
贡献人
前言
.netTiers是针对对象关系映射的一个CodeSmith模板,它采用现成的SQL Server数据库,并为你的应用程序自动生成个性化的DataTiers应用程序块。
主要的特性有:
产生现成的Visual Studio项目和解决方案
完全集成企业库应用程序块框架,用自生插件封装,因而你可以直接用企业库配置控制台来配置你的应用程序
一对一地产生业务对象(实体),一个实体对应一个表,一个属性对应一列
可序列化
触发实体事件
实现了接口IEntity,包含了表中出现的每一个列
对枚举类型及其产生的特别支持
为数据表和视图产生数据访问层组件,来完成以下数据库操作:
基本的CRUD:UPDATE,DELETE,INSERT,SELECT ALL,PAGED SELECT,FIND
按主键查询
按外键查询
按索引查询(非主键和外键)
按连接查询(多对多关系)
支持由命名规则确定的查询产生的用户自定义方法。你也可以从邮件中获取更多的信息
使用子查询和可选的嵌套来完成高级读取和保存
支持分页和排序的查询方法
支持SQL视图
可以选择存储过程或者使用嵌入XML查询文件的参数化SQL语句
使用TList<>和(或)VList为实体和库产生强类型的通用集合。
实现了BingdingList<T>,IBindingListView,IBindingList,IList,ICloneable,IListSource,ITypedList,IDisposable,IComponent,IRaiseITemChangedEvents,IDeserializationCallback等泛型和接口
可排序的,甚至不可排序
可以绑定任意的gridview,datagrid或者任何其他winform和asp.net控件
为分布式编程创建ASP.NET Webservice
创建存储过程脚本并且能自动的安装到服务器
创建完整的NAnt build文件来编译,测试和产生chm/html API文档
创建基于数据库方案的全套验证规则库,并且包括管理你的规则的完整框架
每个对象有其具体类及其继承的基类。这个具体的类一旦被产生,你可以在自己的代码里面使用。每个基类都是分布类型类,你可以毫无障碍地扩展其功能
创建一个EntityDataSource,你将不再被ObjectDataSource的缺点所困扰,.netTiers提供了先进的EntityDataSource,它关联数据仓库并创建100%公开的模型,没有任何后台代码
创建全套的web管理控件,你可以为你的数据库准确快速地建立一个web管理平台
Do I have to keep going, I mean come on, there are features out the wazzuua, download it today...
全套的NUnit测试
代码有详细的注解来描述数据表及其列的扩展属性,遵循微软命名规则
它是免费和开源的!你可以在我们的允许条款内随意的修改模板,捐献出来回馈社区(http://www.sourceforge.net/projects/nettiers)
第一章 概念
这个data tiers的概念包括自定义业务实体组件(数据本身)和数据访问逻辑组件(持久逻辑)两部分。设计的灵感来自于微软的patterns&practices向导Designing Data Tier Components and Passing Data Through Tiers:
第二章 Northwind示例
示例模型
为了阐明模板的原理,我们使用了Employee表:
表2.1. Employee表
产生的OO架构如下:
代码示例:
using Northwind.DataAccessLayer;
// 获取所有的employee,并以LastName升序排序输出
TList<Employees> employees = DataRepository.EmployeesProvider.GetAll();
employees.Sort(EmployeeColumns.LastName, ListSortDirection.Ascending);
foreach(Employees employee in employees)
{
Console.WriteLine("{1} {0}", employee.FirstName, employee.LastName);
}
using Northwind.DataAccessLayer;
// 创建并保存一条记录
Employees employee = new Employees();
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);
//看,新的ID已经增加
Console.WriteLine("New Employee ID" + employee.EmployeeID);
using Northwind.DataAccessLayer;
// 按主键查询和删除
// 示范insert,update,delete方法也可以采用collection作为参数
Employee employee = SqlDataRepository.EmployeeProvider.GetByEmployeeID(13);
DataRepository.EmployeesProvider.Delete(employees);
using Northwind.DataAccessLayer;
// SqlClient可以使用事务处理
// 显示封装了insert,update,delete方法的Save方法
TransactionManager transaction = DataRepository.CreateTransaction();
transaction.BeginTransaction(/*IsolationLevel.ReadUncommited*/);
try
{
// 新增
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);
// 修改employee实例
employee.Notes = "This is a modified fake employee";
// 更新
DataRepository.EmployeeProvider.Save(transaction, employee);
transaction.Commit();
Console.WriteLine("ok");
}
catch(Exception ex)
{
try { transaction.Rollback();} catch(){}
Console.WriteLine("nok : {0}", ex);
}
/*
DeepSave辅助方法能协助你以一次调用来保存对象及其成员
*/
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());
/*
你也可以在配置控制台配置多个数据提供者,用代码来使用其中不是默认的的一个
*/
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";
//要不然,如果你不能预先配置,你也可以在运行时改变连接字符串
using Northwind.DataAccessLayer;
//使用配置的其他连接字符串的新语法
TList<Products> list = DataRepository.Connections["NorthwindConnectionString2"].Provider.CustomersProvider.GetAll();
//使用动态的连接字符串的新语法
DataRepository.AddConnection("DynamicConnectionString", "Data Source=(local);Initial Catalog=Northwind;Integrated Security=true;");
TList<Products> list = DataRepository.Connections["DynamicConnectionString"].Provider.ProductsProvider.GetAll();
this.listBox1.DataSource = list;
this.listBox1.DisplayMember = "ProductName";
this.listBox1.ValueMember = "ProductID";
第三章 配置
以下是配置.netTiers组件的步骤,以Northwind数据库为例。
为了配置你的应用程序来使用.netTiers,你需要增加以下的节到你的App/Web config文件中。在.netTiers 2 Install and Configuration Document你能找到更多的信息。
1. 增加一个新的节到configSettings
<section name="netTiersService"
type="Northwind.DataAccessLayer.Bases.NetTiersServiceSection, Northwind.DataAccessLayer"
allowDefinition="MachineToApplication"
restartOnExternalChanges="true" />
2. 在ConnectionStrings节中增加一项
<connectionStrings>
<add name="netTiersConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=true;Connection Timeout=1;" />
</connectionStrings>
3. 增加netTierServie配置节到你的配置文件中。不使用的时候注释掉即可。
<netTiersService defaultProvider="SqlNetTiersProvider">
<providers>
<add
name="SqlNetTiersProvider"
type="Northwind.DataAccessLayer.SqlClient.SqlNetTiersProvider, Northwind.DataAccessLayer.SqlClient"
connectionStringName="netTiersConnectionString"
useStoredProcedure="false"
providerInvariantName="System.Data.SqlClient" />
</providers>
</netTiersService>
第四章 高级读取和保存
第五章 增加基于存储过程的数据访问方法
概述
你应该增加数据访问组件的新方法到具体的类中,而不是每一次产生类的时候重写基类,具体的类仅仅产生一次。这种解决方案是好的,但是目前有一些缺陷:
为了提供相同的功能你必须重载许多方法,而不是产生代码
可选的解决方法是:从你的存储过程产生方法。为了激活它,你需要设定“Include custom sql”选项为True。这样,你的存储过程名必须以“_TableName_”开始,后面接上你给方法取的名称。这个命名规范保证模板能检测到你的存储过程,从而为正确的数据类(xxTableNameRepository)创建方法。
示例
用一个例子作为解释,考虑Northwind数据库的Product数据表,假设我们需要查询库存在给出值以下的所有产品列表,那么首先我们创建以下存储过程:
-- Get the products that have less units in stock than the @UnitsInStock parameter.
CREATE PROCEDURE dbo._Products_GetWithStockBelow
@UnitsInStock smallint
AS
SELECT
[ProductID],
[ProductName],
[SupplierID],
[CategoryID],
[QuantityPerUnit],
[UnitPrice],
[UnitsInStock],
[UnitsOnOrder],
[ReorderLevel],
[Discontinued]
FROM
[dbo].[Products]
WHERE
[UnitsInStock] < @UnitsInStock
GO
之后我们运行产生器,将看到SqlClient的ProductRepository类的自定义方法(Custom Methods)如下:
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="start">Row number at which to start reading.</param>
/// <param name="pageLength">Number of rows to return.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(int start, int pageLength , System.Int16 UnitsInStock)
{
return GetWithStockBelow(this.transactionManager, this.connectionString, 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="transactionManager"><see cref="TransactionManager" /> object</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(TransactionManager transactionManager , System.Int16 UnitsInStock)
{
return GetWithStockBelow(transactionManager, string.Empty , 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
public ProductCollection GetWithStockBelow(System.Int16 UnitsInStock)
{
return GetWithStockBelow(this.transactionManager, this.connectionString, 0, int.MaxValue , UnitsInStock);
}
/// <summary>
/// This method wrap the '_Products_GetWithStockBelow' stored procedure.
/// </summary>
/// <param name="UnitsInStock"> A <c>System.Int16</c> instance.</param>
/// <param name="start">Row number at which to start reading.</param>
/// <param name="pageLength">Number of rows to return.</param>
/// <param name="transactionManager"><see cref="TransactionManager" /> object</param>
/// <param name="connectionString">Connection string to datasource.</param>
/// <remark>This method is generate from a stored procedure.</remark>
/// <returns>A <see cref="ProductCollection" /> instance.</returns>
protected ProductCollection GetWithStockBelow(TransactionManager transactionManager, string connectionString, int start, int pageLength , System.Int16 UnitsInStock)
{
SqlDataReader reader;
if (transactionManager != null)
reader = SqlHelper.ExecuteReader(transactionManager.TransactionObject, "_Products_GetWithStockBelow", UnitsInStock);
else
reader = SqlHelper.ExecuteReader(connectionString, "_Products_GetWithStockBelow", UnitsInStock);
//Create Collection
ProductCollection rows = new ProductCollection();
Fill(reader, rows, start, pageLength);
reader.Close();
return rows;
}
正如你看到的,所有重载方法被产生,包括SqlClient和WebServiceClient版本并且支持参数和分页。
第六章 NAnt文件
模板将产生一个NAnt的Build文件。这里我不解释什么是NAnt了,你可以从nAnt homepage找到更多的信息。基本上,它是用于在没有visual studio的情况下从命令行编译程序,但是它又不仅仅局限于此,它也可以用于运行Nunit测试和建立NDoc文档。
第七章 模板参数
本模板在许多方面是可设定的:
DataSource 栏
SourceDatabase 你想创建应用程序块的数据库
SourceTables 你想包含到产生器内的数据表列表
EntireDatabase 指明是否所有数据表必须被包含,结果是它将覆盖SourceTables列表
General 栏
OuputDirectory 产生代码的输出路径
BusinessLogicLayerFolderName BLL(实体和实体关系)代码输出文件夹名,推荐为空
DataAccessLayerFolderName DAL(数据仓库)代码输出文件夹名,推荐为:DataAccessLayer
SqlFolderName 数据库存储过程脚本的输出文件夹名,推荐为:SQL
NameSpace 项目的根命名空间。DAL的输出文件夹名将作为DAL的命名空间(命名空间结构即为目录结构)
GenerateUnitTest 指明是否产生测试代码
VsNetIntegration 说明Visual Studio集成的类型:none,single project,separated project(BLL和DAL)
VsNetVersion 说明Visual Studio的版本
WebService参数
GenerateWebService 指明是否asp.net webservice及其对应的DAL必须产生
WebServiceOutputPath asp.net webservice的完整输出路径
WebServiceUrl WebService输出路径所对应的URL
(例如:http://localhost/Services/DatabaseNameRepository)
第八章 单元测试
本模板能可选地产生NUnit测试代码。目前为止,产生的代码包括:
Insert
Update
GetAll
Delete
DeepLoad
Serialization
第九章 建议
数据库设计指南
理想的情况下,为了模板最好的实现,你的数据库应该应用以下的规则:
表名是单一的并且使用Pascal命名方法
字段使用Pascal命名方法并且给出相应的描述
外键关联
要作为查询条件的一个字段或多个字段应该是表的索引
自定义的存储过程名应该以一个下划线开始,后面接表名
表名不要以“Collection”结尾
不要以“ListItem”作为表名
第十章 版本历史
v0.9 - Childebert
v1.0 - Clotaire
v1.1 - Caribert
第十一章 项目信息
描述
本项目是开源的,由sourceforge主持。你也可以通过搜索或者codesmith论坛来获取信息。模板最早是由Ryan Hurdon开发的,现在有John Roland维护。
(贡献人等信息略)
相关文章推荐
- Netties使用说明
- Netties使用说明
- Java中Random的简单使用说明
- 举例说明使用MATLAB Coder从MATLAB生成C/C++代码步骤
- RefactorAsp 的使用说明
- SVN的分支、主干合并的使用说明
- SylixOS 双网卡冗余备份使用说明
- JSP自定义标签的使用说明
- Tortoise SVN使用说明
- Redis--JAVA接口使用说明
- KVM三大存储选项使用说明
- Gradle 教程说明 用户指南 第11章 使用 Gradle 命令行
- 三种内存测试软件的使用说明
- PHPExcel使用说明
- Linux安装rar和unrar命令,及使用说明
- gnuplot使用说明
- Objective-C学习之NSDate简单使用说明
- jd2chm简要使用说明
- Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明
- HIVE WEB INTERFACE使用说明