用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一 ...
随机推荐
- Java 文档注释
Java只是三种注释方式.前两种分别是// 和/* */,第三种被称作说明注释,它以/** 开始,以 */结束. 说明注释允许你在程序中嵌入关于程序的信息.你可以使用javadoc工具软件来生成信息, ...
- MySQL入门(二)
一 MySQL概述 MySQL是一个很受欢迎的开源数据库,当我从Oracle转来做MySQL的时候,感觉最深刻的一点就是,这家伙居然是Server和Storage分开的!而且更不能忍的是,它竟然是插件 ...
- 烂泥:ubuntu下配置msmtp+mutt发送邮件
本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb. 本文主要介绍如何在Linux下使用msmtp+mutt发送邮件,当然Linux下发送邮 ...
- x01.Game.CubeRun: XACT3 播放声音
1.使用 Xact3 工具 在 DXSDK 安装目录 => Uilities => bin => x86 里,运行 Xact3.exe 程序,新建波形库(Wave Bank).声音库 ...
- 用php生成静态html页面(通用2种方法)
因为每次用户点击动态链接的时候都会对服务器发送数据查询的要求 对于一个访问量可能达百万千万级别的网站来说 这无疑是服务器一个大大的负担 所以把动态数据转换成静态html页面就成了节省人力物力的首选 因 ...
- python class对象转换成json/字典
# -*- encoding: UTF-8 -*- class Student: name = '' age = 0 def __init__(self, name, age): self.name ...
- java的访问权限
Java语言中有4中访问修饰符:friendly(默认).private.public和protected. public :能被所有的类(接口.成员)访问. protected:只能被本类.同一个包 ...
- Centos下mysql数据库备份与恢复的方法
一.mysqldump工具备份 mysqldump由于是mysql自带的备份工具,所以也是最常用的mysql数据库的备份工具.支持基于InnoDB的热备份.但由于是逻辑备份,所以速度不是很快,适合备份 ...
- NOIP2010普及组题解 -SilverN
三国游戏 题目内容不放了 由于电脑总是会拆掉最大的组合,所以玩家最多只能得到数值第二大的组合 那么找出第二大的组合就行了 #include<iostream> #include<cs ...
- Vim插件管理——Vundle
Vim插件管理--Vundle 都说Vim时程序员写给自己的编辑器,其中的情结可想而知.身为一只程序狗CodingDoge,今天就让我带各位学习Vim的使用. vim因为其庞大而强劲的插件受到无比的推 ...