首页 > 代码库 > [NHibernate]存储过程的使用(二)
[NHibernate]存储过程的使用(二)
目录
写在前面
文档与系列文章
创建对象
更新对象
总结
写在前面
上篇文章介绍了如何使用MyGeneration代码生成器生成存储过程,以及nhibernate中通过存储过程删除数据的内容,这篇文章将介绍如何创建对象,更新对象。
文档与系列文章
[Nhibernate]体系结构
[NHibernate]ISessionFactory配置
[NHibernate]持久化类(Persistent Classes)
[NHibernate]O/R Mapping基础
[NHibernate]集合类(Collections)映射
[NHibernate]关联映射
[NHibernate]Parent/Child
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nullables
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]基本配置与测试
[NHibernate]HQL查询
[NHibernate]条件查询Criteria Query
[NHibernate]增删改操作
[NHibernate]事务
[NHibernate]并发控制
[NHibernate]组件之依赖对象
[NHibernate]一对多关系(级联删除,级联添加)
[NHibernate]一对多关系(关联查询)
[NHibernate]多对多关系(关联查询)
[NHibernate]延迟加载
[NHibernate]立即加载
[NHibernate]视图处理
[NHibernate]N+1 Select查询问题分析
[NHibernate]存储过程的使用(一)
创建对象
创建对象和删除对象的步骤类似,首先修改Customer.hbm.xml映射文件,添加<sql-insert>节点。调用TB_CustomerInsert存储过程,CustomerInsert 存储过程有四个参数,这里用四个问号表示:
<!--存储过程,check参数:none/rowcount/param--> <sql-insert>exec TB_CustomerInsert ?,?,?,?</sql-insert> <!--<sql-delete check="rowcount" >exec TB_CustomerDelete ?</sql-delete>--> <sql-delete>DELETE FROM [TB_Customer] WHERE [CustomerID] = ? and [Version] =?</sql-delete>
测试
1 /// <summary> 2 /// 通过存储过程添加客户 3 /// </summary> 4 /// <param name="customer">客户实体</param> 5 /// <returns>是否添加成功 </returns> 6 public bool AddCustomerUsingProcess(Customer customer) 7 { 8 try 9 {10 11 var session = NHibernateHelper.GetSession();12 //将customer对象写入内存13 session.Save(customer);14 //更新到数据库15 session.Flush();16 return true;17 }18 catch (Exception ex)19 {20 throw ex;21 }22 }
运行代码,进行测试,此时会有一个异常
int和guid类型不兼容,猜测是存储过程中参数位置不对,调整参数位置。
1 ALTER PROCEDURE [dbo].[TB_CustomerInsert] 2 ( 3 @Version int, 4 @CustomerName nvarchar(16) = NULL, 5 @CustomerAddress nvarchar(128) = NULL, 6 @CustomerID uniqueidentifier OUTPUT 7 8 ) 9 AS10 --去掉SET NOCOUNT ON11 12 INSERT INTO [TB_Customer]13 (14 [Version],15 [CustomerName],16 [CustomerAddress],17 [CustomerID]18 19 )20 VALUES21 (22 @Version,23 @CustomerName,24 @CustomerAddress,25 @CustomerID26 )27 28 RETURN @@Error
数据表
你会发现,在存储过程中的,参数的顺序id必须在后面,乐观并发控制(版本号)必须在第一个。
如果是自增主键,可能遇到的错误可参考:http://www.cnblogs.com/lyj/archive/2008/11/06/1328240.html
更新对象
首先修改映射文件Customer.hbm.xml,添加<sql-update>节点。同理,参数使用?占位。
1 <!--存储过程,check参数:none/rowcount/param-->2 <sql-insert>exec TB_CustomerInsert ?,?,?,?</sql-insert>3 <sql-update>exec TB_CustomerUpdate ?,?,?,?</sql-update>4 <!--<sql-delete check="rowcount" >exec TB_CustomerDelete ?</sql-delete>-->5 <sql-delete>DELETE FROM [TB_Customer] WHERE [CustomerID] = ? and [Version] =?</sql-delete>
测试
1 /// <summary> 2 /// 使用存储过程修改客户信息 3 /// </summary> 4 /// <param name="customer">客户对象</param> 5 /// <returns>是否修改成功</returns> 6 public bool UpdateCustomerUsingProcess(Customer customer) 7 { 8 try 9 {10 11 var session = NHibernateHelper.GetSession();12 //Update the persistent instance with the identifier of the given transient instance.13 session.Update(customer);14 session.Flush();15 return true;16 }17 catch (Exception)18 {19 throw;20 }21 }
此时还会有那个异常,如图,同样的办法修改存储过程。
修改后的存储过程
1 ALTER PROCEDURE [dbo].[TB_CustomerUpdate] 2 ( 3 @Version int, 4 @CustomerName nvarchar(16) = NULL, 5 @CustomerAddress nvarchar(128) = NULL, 6 @CustomerID uniqueidentifier 7 ) 8 AS 9 --SET NOCOUNT ON10 11 UPDATE [TB_Customer]12 SET13 [Version] = @Version,14 [CustomerName] = @CustomerName,15 [CustomerAddress] = @CustomerAddress,16 [CustomerID] = @CustomerID17 WHERE 18 [CustomerID] = @CustomerID19 20 RETURN @@Error
生成的sql语句
exec sp_executesql N‘exec TB_CustomerUpdate @p0,@p1,@p2,@p3‘,N‘@p0 int,@p1 nvarchar(4000),@p2 nvarchar(4000),@p3 uniqueidentifier,@p4 int‘,@p0=3,@p1=N‘wolfy22222‘,@p2=N‘南京22222‘,@p3=‘DDF63750-3307-461B-B96A-7FF356540CB8‘,@p4=2
数据表
你通过数据表中的Version,会发现,它发生了变化,从1到2(出现3的原因,是在之前我测试了一下)。并且在sql语句中有一个@p4的参数。
为了更好的实现版本控制的功能,你可以修改存储过程,添加一个@oldeversion参数。
1 ALTER PROCEDURE [dbo].[TB_CustomerUpdate] 2 ( 3 @Version int, 4 @CustomerName nvarchar(16) = NULL, 5 @CustomerAddress nvarchar(128) = NULL, 6 @CustomerID uniqueidentifier, 7 @oldVersion int 8 ) 9 AS10 --SET NOCOUNT ON11 12 UPDATE [TB_Customer]13 SET14 [Version] = @Version,15 [CustomerName] = @CustomerName,16 [CustomerAddress] = @CustomerAddress,17 [CustomerID] = @CustomerID18 WHERE 19 [CustomerID] = @CustomerID and [Version] =@oldVersion20 21 RETURN @@Error
在映射文件中,添加一个?,代表@oldVersion。
1 <sql-update>exec TB_CustomerUpdate ?,?,?,?,?</sql-update>
生成的sql语句为
这样就跟存储过程中的参数对应上了。
上篇文章也介绍了一种方法,如果你不想执行存储过程,可以使用sql语句也可以达到目的。
1 <sql-update>UPDATE TB_CustomerUpdate SET Version=?, [CustomerName]=?,[CustomerAddress]=? WHERE CustomerID=? AND Version=? </sql-update>
总结
本篇文章介绍了如何在nhibernate使用存储过程添加数据,更新数据及在使用过程中需要注意的问题。你可能也有个疑问,为啥使用MyGeneration生成的存储过程,每次都要修改?这个的确是个很让人恼火的地方,没办法,并不能什么东西都十全十美,至少存储过程的语法已经写好了,修改起来也很方便。
[NHibernate]存储过程的使用(二)