用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一 ...
随机推荐
- DDL触发器的应用
一般来说,DML触发器可以监测得到具体对象的具体数据的变更.然而,DDL触发器则能够对一些服务器的行为作出监控,比如我们可以利用DDL触发器来做登录限制啊,做一些日志控制啊之类的. 好,然后简单粗暴上 ...
- SQL Server 2008 R2——PIVOT 行转列 以及聚合函数的选择
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- Hadoop HDFS Basic JAVA API
org.apache.hadoop.fs.FileSystem 是HDFS的文件系统抽象,在分布式系统中管理HDFS文件和目录.文件内容存储在由多个相同大小的块(如64M)构成的datanode节 ...
- 学会使用简单的 MySQL 常用操作
一.MySQL 数据库的基本安装 # yum 安装 mysql 版本:5.1.73 [root@mysql ~]# yum install -y mysql-server mysql # 启动 MyS ...
- mysql连接报错 Host ‘xxx’is blocked because of many connection errors;unblock with 'mysqladmin flush-hosts'
程序无法连接MySQL,提示: null, message from server: "Host '192.168.6.68' is blocked because of many con ...
- linux原始套接字(2)-icmp请求与接收
一.概述 上一篇arp请求使用的是链路层的原始套接字.icmp封装在ip数据报里面,所以icmp请 ...
- PHPstudy和ecshop的安装和使用
PHPstudy和ecshop: phpStudy是一个PHP调试环境的程序集成包. 该程序包集成最新的Apache+PHP+MySQL+phpMyAdmin+ZendOptimizer,一次性安装, ...
- java 22 - 6 多线程之线程调度和设置线程的优先级
线程调度 假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令. 那么Java是如何对线程进行调用的呢? 线程有两种调 ...
- Js倒计时程序
Js倒计时程序 点击下载
- AFNetworking 与 UIKit+AFNetworking 详解
资料来源 : http://github.ibireme.com/github/list/ios GitHub : 链接地址 简介 : A delightful iOS and OS X networ ...