1. C# Class 和hbm文件的一对多的类型对照关系
Iesi.Collections.dll程序集中的ISet集合
//ISet ---> hbm <set>
//IList ---> hbm <bag>
2. 可以为数据庫的View,建一个Class文件,原理和Table一样, 只读的用Private Set
3. //automatic property only work at C#3.0 above,属性都要用virtual,因为所有读取都有hibernate控制
public virtual string productName { get; private set; }
4. many to many 必须指定column,不然export schema 时会多出來一个elt列
one to many的 key column 是指数据庫1:n的多方的外键列的名字
5. <!-- HQL don't support left join on xxx, so use filter instead-->
<filter-def name="regionFilter" condition="region=:region">
<filter-param name="region" type="string"/>
</filter-def>
6. /// HQL 是对类(对象)进行查询,所以from的对象一定要是C# 类名
/// Path expected for join! 是什么原因? 如果两个类的hbm没有设置关联
/// 只能用from A, B where A.field=B.field, 不能用A join B
7. hibernate.cfg.xml 里面定义实体在哪里读取
<!--从领域模型层的dll读入实体定义,也可以在C#代码读入 Configuration.AddAssembly()-->
<mapping assembly="DomainModel" />
初始化示例代码
//create configuration
var cfg = new Configuration();
//we use hibernate.cfg.xml as default name, no need for filename parm
cfg.Configure();
8. 单例模式的helper
public class NHibernateHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if(_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
9 NH默认是Lazy Load, 要立即加载,有3个方法
立即加载的三个方法:1. 在xxx.hbm.xml定义lazyload=false
2.NHibernateUtil.Initialize(product.ProductAttribute);
3, HQL join fetch, 但是用了fetch,
setMaxResults() 或setFirstResult()就不会生成数据庫优化的top N等分页的语句了
9 //HQL 对于多对多查询很没有效率,因为它要连接3张表,如果数据量多的话,查找记录数也会timeout
return session.CreateSQLQuery(Sql)
.AddEntity(typeof(Product))
.SetFirstResult((CurrentPage - 1) * PageSize)
.SetMaxResults(PageSize)
.List<Product>();
10 建议用TestDriven.net 进行单元测试,用NH Profiler 查看优化HQL语句
11 1对多和多对多都可以在hbm文件里面设置inverse=true/false来指定由哪一端来保存关联记录.
1对多由子端维护较好(child.parent=xxx),因为不用每次都取一次集合parent.children().add
多对多m:n 时多对多没有主次之分,如果后面的代码要用到双向的集合,保存时的两边都要save!
否则只是保存到数据库,由主控方保存就可以
12 在gridview的BoundField列,不能直接显示关联对象主键ID, 要显示的话有三个方法
a.在类定义里加一个字段包装,例如order加了个string类型的customer
b. 在Row_DataBound里面处理
c. 直接在aspx页面用模版列取值(对象.属性)
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("_Warehouse.ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
13 HQL 语法的tricky: Inventory类有2个属性_Warehouse和_Product,对应的数据庫字段是warehouse,product, 下面3条HQL结果都一樣.
a) From Inventory where warehouse='001' and product='p001'
b) From Inventory where _Warehouse='001' and _Product='p001'
c) From Inventory where _Warehouse.ID='001' and _Product.ID='p001'
推荐使用第2条,第1条不知道算不算HQL的bug,还是故意这样的?
14 Nhibernate操作原生SQL以及查询DataTable
public virtual DataTable ExecuteDataTable(string sql)
{
try
{
IDbCommand command = Session.Connection.CreateCommand();
command.CommandText = sql;
IDataReader reader = command.ExecuteReader();
DataTable result = new DataTable();
result.Load(reader);
return result;
}
catch (Exception ex)
{
}
return new DataTable();
}