[NHibernate]存储过程的使用(二)
目录
写在前面
上篇文章介绍了如何使用MyGeneration代码生成器生成存储过程,以及nhibernate中通过存储过程删除数据的内容,这篇文章将介绍如何创建对象,更新对象。
文档与系列文章
[NHibernate]持久化类(Persistent Classes)
[NHibernate]集合类(Collections)映射
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]条件查询Criteria Query
创建对象
创建对象和删除对象的步骤类似,首先修改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 AS 10 --去掉SET NOCOUNT ON 11 12 INSERT INTO [TB_Customer] 13 ( 14 [Version], 15 [CustomerName], 16 [CustomerAddress], 17 [CustomerID] 18 19 ) 20 VALUES 21 ( 22 @Version, 23 @CustomerName, 24 @CustomerAddress, 25 @CustomerID 26 ) 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 ON 10 11 UPDATE [TB_Customer] 12 SET 13 [Version] = @Version, 14 [CustomerName] = @CustomerName, 15 [CustomerAddress] = @CustomerAddress, 16 [CustomerID] = @CustomerID 17 WHERE 18 [CustomerID] = @CustomerID 19 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 AS 10 --SET NOCOUNT ON 11 12 UPDATE [TB_Customer] 13 SET 14 [Version] = @Version, 15 [CustomerName] = @CustomerName, 16 [CustomerAddress] = @CustomerAddress, 17 [CustomerID] = @CustomerID 18 WHERE 19 [CustomerID] = @CustomerID and [Version] =@oldVersion 20 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生成的存储过程,每次都要修改?这个的确是个很让人恼火的地方,没办法,并不能什么东西都十全十美,至少存储过程的语法已经写好了,修改起来也很方便。
-
博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。