Smart Code Generator 的 NHibernate 模板






4.77/5 (19投票s)
介绍了如何使用 Smart Code 生成 NHibernate 对象和 ASPX 页面。

引言
要了解更多关于 Smart Code 的信息,请点击此处阅读下一篇文章。
示例代码和模板基于下一篇文章 NHibernate 与 ASP.NET 的最佳实践。在这篇出色的文章中,Billy McCafferty 描述了如何利用 NHibernate 1.2 和 ASP.NET 优势的最佳实践。
在这篇文章中,我们将尝试创新……我们将使用 Northwind 数据库作为示例,但这些示例适用于任何数据库
ASPX 模板中的错误修复,按 ID 方法加载页面
代码生成,简要概述
Smart Code 工具可以自动生成与数据库系统交互的程序和组件。它通过读取数据库Schema,允许用户为表和列设置某些扩展属性,并对每个表应用模板来生成代码。模板本身是访问 Smart Code 对象模型以生成定制程序和组件的程序。虽然 Smart Code 提供了一套基本模板,但用户可以编辑这些模板或创建自己的模板以适应其特定的项目需求。此外,模板可以用 C# 或 VB.NET 编写(理论上可以用任何支持创建动态链接库的 .NET 语言编写)。
快速入门指南
Smart Code 是一个非常强大的工具,学习如何使用它的最佳方法或许是查看一个示例应用程序的运行,然后返回来检查 Smart Code 的哪些功能负责实现该应用程序的功能。
- 在 web.config 中修改 connection.connection_string 值
- 使用应用程序,打开不同的页面并输入一些数据。
- 使用 Smart Code 的最新版本打开 Newin.scp 项目。
- 编译 NHibernateTemplates 和 WebTemplates 并将 dll 加载到 Smart Code 中。
- 更改 Newin.scp 项目中的一些属性,这将向您展示不同属性设置和模板分配的效果。
NHibernate 模板库
示例包附带一套模板库,用于生成使用 NHibernate 访问和修改数据的三层、基于 Web 表单的解决方案。这套库用于生成 C# 代码;(未来版本将支持生成 VB.NET 代码)。
此外,示例包还包括 Visual Studio.NET 中的 Northwind 示例项目,以便与这些库配合使用,从而可以直接将生成的代码拖放到其中。
领域层
有关领域层的描述,请点击此处
领域层描述了数据访问对象以及用于在各层之间传输数据的所有对象类
生成分离接口 IDAOFactory
IDAOFactory 接口提供获取作为 DAO 的对象的方法。此类别作为抽象数据。在 Smart Code 项目中为所有实体生成 IDAOFactory 的模板是 NHibernateTemplates 项目中的 IDaoFactory 类。
请注意,如果选中该项目,模板将只运行一次,因为它是一个项目级模板。
IDAOFactory 生成的代码如下所示
using System; using System.Collections.Generic; namespace Northwind.Core.DataInterfaces { public interface IDaoFactory { ICategoryDao GetCategoryDao(); ICustomerCustomerDemoDao GetCustomerCustomerDemoDao(); ICustomerDemographicDao GetCustomerDemographicDao(); ICustomerDao GetCustomerDao(); IEmployeeDao GetEmployeeDao(); IEmployeeTerritoryDao GetEmployeeTerritoryDao(); IOrderDetailDao GetOrderDetailDao(); IOrderDao GetOrderDao(); IProductDao GetProductDao(); IRegionDao GetRegionDao(); IShipperDao GetShipperDao(); ISupplierDao GetSupplierDao(); ITerritoryDao GetTerritoryDao(); } }
数据接口
模板 DataInterfaces 为支持每个具体的 DAO 工厂生成代码。每个工厂都是一个独立于数据库的实现,其中实现将是特定于数据库的。
用于生成 DataInterfaces 的模板如下图所示
产品表生成的代码如下所示
using System;
using System.Collections.Generic;
using Northwind.Core.Domain;
namespace Northwind.Core.DataInterfaces
{
/// Since this extends the IDao{TypeOfListItem, IdT} behavior, it's a good idea to
/// place it in its own file for manageability. In this way, it can grow further without
/// cluttering up IDaoFactory.
public interface IProductDao : IDao<Product, System.Int32>
{
}
}
将领域映射到数据库,HBM-XML 文件
NHibernateTemplates 项目提供了一个类 NHibernateHbm,用于为 NHibernate 生成映射文件
此模板为具有单个和复合键的表以及将被识别并创建适当的一对多或多对多映射的链接表生成 HBM 文件
具有单个键的表的 Hbm
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Northwind.Core" namespace="Northwind.Core.Domain">
<class name="Product" table="Products" >
<id name="ID" type="System.Int32" column="ProductID">
<generator class="identity"/>
</id>
<property name="ProductName" column="ProductName" type="System.String" not-null="true" length="40"/>
.............
<many-to-one name="CategoryIDCategories" column="CategoryID" class="Category" update="0" insert="0" />
<many-to-one name="SupplierIDSuppliers" column="SupplierID" class="Supplier" update="0" insert="0" />
<bag name="OrderDetailses" table="Order Details" inverse="true" lazy="true" cascade="delete">
<key column="ProductID" />
<one-to-many class="OrderDetail"/>
</bag>
</class>
</hibernate-mapping>
具有复合键的表的 Hbm
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Northwind.Core" namespace="Northwind.Core.Domain">
<class name="EmployeeTerritory" table="EmployeeTerritories" >
<composite-id name="ID" class="Northwind.Core.Domain.EmployeeTerritory+DomainObjectID">
<key-property type="System.Int32" name="EmployeeID" column="EmployeeID" />
<key-property type="System.String" name="TerritoryID" column="TerritoryID" />
</composite-id>
<many-to-one name="EmployeeIDEmployees" column="EmployeeID" class="Employee" update="0" insert="0" />
<many-to-one name="TerritoryIDTerritories" column="TerritoryID" class="Territory" update="0" insert="0" />
</class>
</hibernate-mapping>
多对一和 bag 是从表之间的外键关系(InReferences 和 OutReferences)创建的,这些引用在您构建域时创建,下图显示了此概念

产品表和区域表都通过 Out References (OutReferences) 与 EmployeeTerritories (InReferences) 相关联。
生成 C# 类
NHibernateTemplates 项目提供了类 NHibernateClass,用于为 NHibernate 生成 C# 类

与映射一样,NHibernateClass 支持单键和复合键,关于 ID,请参阅 NHibernate 与 ASP.NET 最佳实践文章中的通用 ID 和对象比较部分。
以下代码显示了如何生成复合键代码的示例
using System;
using System.Collections.Generic;
namespace Northwind.Core.Domain
{
/// <summary>
/// EmployeeTerritory object for NHibernate mapped table EmployeeTerritories.
/// </summary>
[Serializable]
public class EmployeeTerritory : DomainObject<EmployeeTerritory.DomainObjectID>
{
[Serializable]
public class DomainObjectID
{
private System.Int32 _EmployeeID;
private System.String _TerritoryID;
public DomainObjectID() { }
public DomainObjectID(System.Int32 employeeID, System.String territoryID)
{
_EmployeeID = employeeID;
_TerritoryID = territoryID;
}
public System.Int32 EmployeeID
{
get { return _EmployeeID; }
protected set { _EmployeeID = value; }
}
public System.String TerritoryID
{
get { return _TerritoryID; }
protected set { _TerritoryID = value; }
}
public override bool Equals(object obj)
{
if (obj == this) return true;
if (obj == null) return false;
DomainObjectID that = obj as DomainObjectID;
if (that == null)
{
return false;
}
else
{
if (this.EmployeeID != that.EmployeeID) return false;
if (this.TerritoryID != that.TerritoryID) return false;
return true;
}
}
public override int GetHashCode()
{
return EmployeeID.GetHashCode() ^ TerritoryID.GetHashCode();
}
}
private Employee _EmployeeIDEmployees;
private Territory _TerritoryIDTerritories;
public EmployeeTerritory()
{
}
public EmployeeTerritory(DomainObjectID id)
{
base.id = id;
}
public virtual System.Int32 EmployeeID
{
get { return base.id.EmployeeID; }
}
public virtual System.String TerritoryID
{
get { return base.id.TerritoryID; }
}
public virtual Employee EmployeeIDEmployees
{
get { return _EmployeeIDEmployees; }
set { _EmployeeIDEmployees = value; }
}
public virtual Territory TerritoryIDTerritories
{
get { return _TerritoryIDTerritories; }
set { _TerritoryIDTerritories = value; }
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
}
}
其中 EmployeeTerritory+DomainObjectID 覆盖 Equals 和 GetHashCode 方法。
用于列出记录的 Web 表单
这些模板生成用于列出记录的 Web 表单。它们都将记录显示在 ASPGrid 中,一次显示 20 条记录(默认),并带有用于浏览网格内容的控件;此外,可以单击列标题对行进行排序和分页。

网格中的每一行都有超链接,用于编辑和查看相应的记录,页面中还包含一个“添加”按钮以创建新记录。页面加载时会自动填充网格
用于编辑记录的 Web 表单

这些模板生成用于创建和编辑记录的 Web 表单。

此外,这些模板还识别诸如 Control 属性已设置为 ComboBox 或 Check Box 的属性。
ComboBox 控件与 LOV 属性结合使用,可在下拉 Web 控件中生成自定义 DataTextField 属性。
摘要
Smart Code 模板的可能性是无限的。Smart Code 是一个功能异常强大的开发人员生产力工具。与 NHibernate 模板结合使用,您可以在几分钟内编写应用程序的基础代码。
Web 应用程序项目
示例代码使用 Web 应用程序项目类型的网站来构建 Web 应用程序。这种类型的网站与 .Net Framework 1.1 模型非常相似。
您可以从 http://download.microsoft.com/download/9/0/6/906064ce-0bd1-4328-af40-49dca1aef87c/WebApplicationProjectSetup.msi 获取 Web 应用程序项目的安装程序。下载后即可运行。
更新日志
- 复合键定义中的小错误修复