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
               entity.Customer =  order._Customer.ID;
 
b. 在Row_DataBound里面处理
    Label gv_lblCompany = (Label)e.Row.FindControl("gv_txtCompany");
    gv_lblCompany.Text = entity[idx]._Company.ID;
 
c. 直接在aspx页面用模版列取值(对象.属性)
                <asp:TemplateField>
                        <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();

}


    

 

 

posted on 2009-11-09 17:57  Gu  阅读(777)  评论(2编辑  收藏  举报