1、实体bool类型属性与数据库映射。如实体中有bool属性IsDelete.配置如下
<property column="IsDelete" name="IsDelete" type="YesNo" ></property>
或者
<property name="Deleted" type="NHibernate.Type.YesNoType,NHibernate">
<column name="Deleted" sql-type="char(1)" default="0" not-null="true"></column> </property>2、若将数据写入到表时,希望某个字段不被写入则如下映射
<property column="IsDelete" name="IsDelete" insert="false"></property>
3、两个对象之间多对多时,生成两个表之间的映射关系表.如一下生成 人员与公司之间的映射关系表UserCompanyMap.UserID与CompanyID作为联合主键
<set name="Companies" table="UserCompanyMap" >
<key column="UserID" /> <many-to-many column="CompanyID" class="Domain.Company,Domain" /> </set>4、通过ICritetia接口做关联查询;如有many-to-one关系的Profile和Department。现在希望通过sql直接查询返回dto ProfileDTO 。sql如下;
SELECT p.ItemID, p.Name, p.Summary, d.ItemID, d.Name FROM Profile p inner join Department d on p.DepartmentID = d.ItemID
public class ProfileDTO { private int _itemID; private int _departmentID; private string _departmentName; private string _name; private string _summary; public virtual int ItemID { get { return _itemID; } set { _itemID = value; } } public virtual int DepartmentID { get { return _departmentID; } set { _departmentID = value; } } public string DepartmentName { get { return _departmentName; } set { _departmentName = value; } } public string Name { get { return _name; } set { _name = value; } } public string Summary { get { return _summary; } set { _summary = value; } } }
public static IList List() { ICriteria criteriaSelect = Persistence.Session.CreateCriteria(typeof(Profile)); criteriaSelect.CreateAlias("Department", "d"); criteriaSelect.SetProjection( Projections.ProjectionList() .Add(Projections.Property("ItemID"), "ItemID") .Add(Projections.Property("Name"), "Name") .Add(Projections.Property("Summary"), "Summary") .Add(Projections.Property("d.ItemID"), "DepartmentID") .Add(Projections.Property("d.Name"), "DepartmentName")); criteriaSelect.AddOrder(Order.Asc("Name")); criteriaSelect.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(ProfileDTO))); return criteriaSelect.List(); }
5、ICriteia 接口进行数据分页查询时,一般情况下,可能如下使用:
ICriteria criteria = session.CreateCriteria(typeof(T)); foreach (ICriterion cri in queryConditions) { criteria.Add(cri); } ICriteria criteriaRowCount = CriteriaTransformer.Clone(criteria); recordCount = criteriaRowCount.SetProjection(Projections.RowCount()) .UniqueResult (); foreach (ICriterion cri in queryConditions) { detachedCriteria.Add(cri); }
if (IsPage)
{ int skipCount=(pageIndex - 1)*pageSize; criteria.SetFirstResult(skipCount).SetMaxResults(*pageSize); }criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());
return criteria.List();
但是这样可能会导致数据分页出现问题。如果实体T没有和其他表的关联关系,这样取数据显然是可行的。但是如果关联过多,而T又不是领域里的聚合根,则可能导致分页问题。
原因是NHibernate使用left join 关联多表进行查询时,查询出满足条件的数据,然后按照SetFirstResult(skipCount).SetMaxResults(*pageSize)进行获取,然后去重,再显
示,这样在过滤掉重复数据后,返回的数据就会比pageSize少。如果pageSize比NHibernate进行left join 后的结果还多的话,那就没有问题。但是一旦pageSize少于left join的
记录数,则分页还存在问题.
解决办法:
ICriteria criteria = session.CreateCriteria(typeof(T)); foreach (ICriterion cri in queryConditions) { criteria.Add(cri); } ICriteria criteriaRowCount = CriteriaTransformer.Clone(criteria); recordCount = criteriaRowCount.SetProjection(Projections.RowCount()) .UniqueResult (); int skipCount = (pageIndex - 1)*pageSize; criteria.AddOrder(new Order(orderField, isAscending)); DetachedCriteria detachedCriteria = DetachedCriteria.For(); detachedCriteria.SetProjection(Projections.Distinct(Projections.Id())); foreach (ICriterion cri in queryConditions) { detachedCriteria.Add(cri); } List
criteria.Add(Restrictions.In(GetIndentity(), list));//GetIndentity () 获取实体标识名,即对应数据库主键的实体属性名称
criteria.SetResultTransformer(new DistinctRootEntityResultTransformer()); return criteria.List();
6、持久化枚举类型
<property name="HouseType">
<column name="HouseType" sql-type="varchar(10)" default="0" not-null="true"></column> </property>
7、Hql查询直接返回对象
const string hql = @"SELECT new KeyValuePair(COUNT(log.Point) ,user.DepartmentName) FROM Log log ,User user WHERE log.UserGuid=user.UserGuid GROUP BY user.DepartName"; IQuery query = session.CreateQuery(hql); return query.List();
同时需要给KeyValuePair定义映射,(不需要映射到表)如:
8、NHibernate的日志不影响你使用Log4Net写日志
使用Log4Net
ILog Log= LogManager.GetLogger("myLog"); Log.Info("记录日志");
9、配置C# Decimal类型
10、配置属性说明:
1)<property>元素 insert属性:设置为false,在insert语句中不包含这个字段,表示永远不会被插入,默认true
2)<property>元素 update属性:设置为false,在update语句中不包含这个字段,表示永远不会被修改,默认true 3)<class>元素 mutable属性:设置为false就是把所有的<property>元素的update属性设置为了false,说明这个对象不会被更新,默认true 4)<property>元素 dynamic-insert属性:设置为true,表示insert对象的时候,生成动态的insert语句,如果这个字段的值是null就不会加入到insert语句当中.默认false 5)<property>元素 dynamic-update属性,设置为true,表示update对象的时候,生成动态的update语句,如果这个字段的值是null就不会被加入到update语句中,默认false 6)<class>元素 dynamic-insert属性:设置为true,表示把所有的<property>元素的dynamic-insert属性设置为true,默认false 7)<class>元素 dynamic-update属性:设置为true,表示把所有的<property>元素的dynamic-update属性设置为true,默认false
参考: