用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一 ...
随机推荐
- Boost配置
=================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载 请通过右 ...
- MySQL的Explain命令
Explain命令是查看查询优化器如何决定执行查询的主要办法. 调用 EXPLAIN 要使用EXPLAIN,只需在查询中的SELECT关键字之前增加EXPLAIN.MySQL会在查询上设置一个 ...
- 3.Docker - 镜像管理
一.使用容器生成镜像 1.进入容器,安装软件包(任意包) 1 2 3 4 5 6 7 bash-3.2# docker ps -a CONTAINER ID IMAGE ...
- getaddrinfo
gethostbyname和gethostbyaddr这两个函数仅仅支持IPv4,getaddrinfo函数能够处理名字到地址以及服务到端口这两 种转换,返回的是一个sockaddr结构的链表而不是一 ...
- proteus 查找 仿真元件 中英文对照 [持续更新]
CRYSTAL 晶振 CAP 电容 RES 电阻 LED 灯 DIODE 二极管 POWER 电源 GND 接地 SPEAKER 扬声器 AT89C51 51 CPU芯片 三极管 PNP N ...
- 几种语言的CGI编程
为了了解PHP.JSP.ASP出现之前人们写网站的方法,洒家研究了一波CGI,使用C.Python.batch.shell script语言写了几个简单的网页. CGI即通用网关接口,指web服务器调 ...
- xsd.exe的使用
xsd.exe的使用 XML文件生成XSD文件 xsd myFile.xml /outputdir:myOutputDir XSD文件生存实体类 xsd <你的XSD路径>.xsd / ...
- dba诊断之IO
--查看占用系统io较大的session SELECT se.sid,se.serial#,pr.SPID,se.username,se.status,se.terminal,se.program ...
- ARM学习篇 SDRAM理解
1.SDRAM单管存储单元 SDRAM单管电路图 C记忆单元 T控制门管 Z字线 W位线 注:图示为N沟道耗尽型MOS管 写入:Z加高电平,MOS导通,W状态决定了电容C的状态 读出:Z加高电平,MO ...
- 台湾辅仁大学的python教程笔记
散记,因为主讲老师讲得也很乱..说课后的自习才是最重要的- 1.就这样,笔记看下.. 2. Modules 模组 很多模组放在一起就是一个packages 一个packages 一定有有__init_ ...