用nhibernate的几点小经验
最近几个月都在用nhibernate做项目。写几点经验。
1. 解决Transient object exception
原项目是用Entity Framework做的。现在是用nhibernate代替Entity framework. 原来的Entity framework可以new 一系列的对象,这些对象之间还有一对多关系,这些对象都没有保存,然后一起保存,就会出现这个问题。例如:Project 对应多个ProjectVersion, 一个ProjectVersion对应多个 ProjectVersionAttribute, 在最后的时候保存Project, 此时Project, ProjectVersion, ProjectVersionAttribute都是没有保存的。都是刚new出来的。 调用Project.Save(); 即出现这个问题。后来查阅文档, 原来是map的问题,没有设置级联保存。于是就在map文件里加上了cascade.all。这样的话,在处理刚才这种情况时就没有问题。所有这些没有保存的对象都会由于这个级联设置而保存了。Entity framework的map是在dbml中设置一下就可以了。而nhibernate需要写map文件。这个差别还是比较大的。
2. 解决对象树中的子对象不刷新问题。
还以Project -> ProjectVersion -> ProjectVersionAttribute来说示例。在ProjectVersionAttribute中加了一个新对象,新对象保存了。然后在Project级别重新Load数据,然后通过Project的属性来一层层地访问所有的子对象。但是这个对象树总是没有新加入的对象。这对我们遍历这个对象树有点问题。这个问题开始以为是跟cascade有关。试着加上了cascade,但是没有作用,新加的子对象还是没有出现在对象树中。最后没有办法了,只有放弃当前Session,新建一个Session,再装入对象树,结果就对了。
3. nhibernate用LINQ和lamda表达式
默认情况下nhibernate用HQL, 在.net版本下,可以用LINQ来写查询。nhibernate可以利用LINQ的语句。Entity framework写的应用,原来有很多LINQ语句,有的还特别复杂,长达好几页。可以用NHibernate.Linq名称空间,然后用形式如:session.Query<User>().Where(u => u.Username== username)或者
session.QueryOver<User>().Where(u => u.Username== username),就可以跟LINQ和lamda表达式很兼容了。Query和QueryOver两个大体都差不多。我们项目里实际用的是QueryOver。通过这种方式,原来的Entity framework的有LINQ和lamda query就可以不用改了。绝大部分都可以用。
4. NullPointerException的解决方式
在nhibernate中一条条记录都成了一个个对象。数据库表的外连接在nhibernate的map中是reference。这个外键是不允许空的。数据库中外键字段不可能空的。但是内存中的对象就不一样了。内存中的对象某个属性可以随便取什么值,为空也可以。我们在LINQ查询lamda表达式中引用到了某个属性,如果这个属性为null,则会抛出NullPointerException。这种情况在nhibernate中发生很普遍,而Entity framework这种问题就少些。对于这个NullPointerException,我们需要保证每个属性都有正确的值,而不能是只给主键赋一个值就行了。nhibernate不会自动根据主键去取到除主键外的其他字段的。我们得构造一个完整的对象。这样在查询的时候就不会出现NullPointerException的问题。有时一个表里有很多条记录,如果某个字段允许空,同时某些记录的该字段是空值,查询条件里的lamda表达式有用到该字段。很有可能出现NullPointerException的问题。按以上条件查找哪些lamda表达式涉及的字段,然后给LINQ查询加上检查空的条件。这样就可以避免出NullPointerException了。
5. 同一记录被两个Session装载了。
因为asp.net的环境是多线程的。可能会出现两个以上的Session, 如果同条数据库记录被两个Session装载到内存中,其中一个Session就会报错。这个问题就是属于Session管理的问题了。数据库表有一定的工作区域的,比如有的表是跟用户的,有的是跟项目的,如果在业务上可以让不同Session总是访问不同的数据。那么这个问题就不会出现了。但是数据库里总是有一些公用的数据。这些数据呢我们可以一次性读入到内存里缓存起来。缓存以后我们就让这些公用数据同原来的Session脱离。让其处于瞬态。需要的时候再与某个Session连接,进入持久化状态。
6. nhibernate数据库事务的粒度问题
最开始的时候我们 nhibernate的数据库事务粒度相当小,所有insert, update, delete, select都单独成一个事务。后来发现这样不能适合实际的要求。有些时候需要引入更大的数据库事务粒度。比如好几个insert, update, delete构成一个事务。这个事务的控制就在商务逻辑的类中来管理的。这里可以引入Unit of work模式,也可以引入自己管理的事务模式。
用nhibernate的几点小经验的更多相关文章
- 你应该知道的那些Android小经验
原文出处:http://jayfeng.com/ 做Android久了,就会踩很多坑,被坑的多了就有经验了,闲暇之余整理了部分,现挑选一些重要或者偏门的“小”经验做个记录. 查看SQLite日志 ad ...
- Android开发的16条小经验总结
Android开发的16条小经验总结,希望对各位搞Android开发的朋友有所帮助. 1. TextView中的getTextSize返回值是以像素(px)为单位的, 而setTextSize()是以 ...
- Android小经验
转载自:http://mp.weixin.qq.com/s?__biz=MzA4MjU5NTY0NA==&mid=404388098&idx=1&sn=8bbbba7692dc ...
- gulp+webpack+angular1的一点小经验(第二部分webpack包起来的angular1)
又一周过去了,项目也已经做得有点模样了.收集来一些小经验,分享给大家,有疏漏之处,还望指正,海涵. 上周整合了gulp与webpack,那么工具准备差不多了,我们就开始编码吧.编码的框架就是angul ...
- 分享调试SI4432的一些小经验(转)
分享调试SI4432的一些小经验 最近使用 STM8F103 + SI4432 调无线,遇到问题不少,此处有参考过前辈的经验: 1.硬件把板给到我时USB烧录线带供电(5V),此供电接到LDO输出,就 ...
- Duilib 开发中的小经验
# duilib开发中收集的小代码 # ## 1 窗体创建 ## - 窗体多继承于 public WindowImplBase ,简单的定义几个函数就可以实现:拖曳caption移动(设置xml窗体的 ...
- String、StringBuffer、StringBuilder的一些小经验……
一说String.StringBuffer和StringBuilder,想必大家都很熟悉,这三者经常在我们的面试题中出现,我也是看到了关于这三个的经典面试题,才触动了我之前工作中的一些经历,故而根据我 ...
- APP落地页开发中的一些小经验~
在开发日常落地页的时候,每当碰到一些很酷炫的宣传图用css实现很复杂且耗时的时候,一般采取切图然后将其放在页面中,在这个过程中发现<img/>标签中图片下方会有一行小空白,影响了与后一部分 ...
- 在vs2010中mfc,C++的一些小经验
1 如果你最近才从vc6.0到vs2010,在vs2010中mfc可能遇见一个小问题,如果你添加或改天了窗口中的控件,运行程序缺没有发现其中的变化,这时候需要在debug选项中rebuild all一 ...
随机推荐
- 使用C/C++,赋值运算时发生的转换
使用C/C++,赋值运算时发生的转换主要有以下四种情况 一: 两边类型不同: 结果: 自动完成类型转换! 二: 长数赋给短数: 结果: 截取长数的低位送给短数! 三: 短数赋给长数: 结果: 原来是什 ...
- MySQL [Warning]: IP address 'xxxx' could not be resolved: Name or service not known
MySQL的error log 出现大量的 DNS反解析错误. DNS解析是指,将 域名解析成ip地址: DNS反解析是指,将IP地址反解析成域名: Version: MySQL Community ...
- MongoDB与衍生版的TokuMX对比
为什么会出现TokuMX呢? 查阅大量的资料和翻阅一些大牛的博客发现,MongoDB作为nosql派别的一个典型非关系型数据库其实存在许多缺陷不足之处. 然后肯定就会有有人跳出来,来做一个衍生的东西, ...
- 烂泥:高负载均衡学习haproxy之TCP应用
本文由ilanniweb提供友情赞助,首发于烂泥行天下 在前几篇文章中,我们介绍了haproxy的配置参数,而且配置例子都是http协议(7层应用)的. 这篇文章,开始介绍haproxy的4层TCP应 ...
- android 利用Path.cubicTo 画 贝塞尔曲线
Path.cubicTo void android.graphics.Path.cubicTo(float x1, float y1, float x2, float y2, float x3, fl ...
- scp报错:not a regular file,解决方法:加参数 -r
命令:scp -P1234 /data/aa root@192.0.0..0:/data 文件结构:/data/aa/yearmonth=2015-09 报错:not a regular fi ...
- 当Sublime Text 2 遇到 EOFError: EOF when reading a line
重新用Sublime Text, command+B运行一小段python程序时遇到 EOFError: EOF when reading a line 似曾相识哪里见过,但是想不起来该如何解决了 S ...
- MySQL Database on Azure 的用户名
MySQL Database on Azure是中国版Windows Azure上的一个PaaS服务,类似于AWS上的RDS.MySQL Database on Azure的用户名与on-premis ...
- Linux Philosophy
These days I read the book Linux and the Unix Philosophy. Here are some principles: Little is gracef ...
- POJ1062昂贵的聘礼[最短路建模]
昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 45892 Accepted: 13614 Descripti ...