[NHibernate]视图处理
目录
写在前面
前面的文章主要讲了对物理数据表的操作,当然了Nhibernate同样可以操作视图,本文将讲nhibernate对视图操作的种种。
文档与系列文章
[NHibernate]持久化类(Persistent Classes)
[NHibernate]集合类(Collections)映射
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]条件查询Criteria Query
视图
首先创建一个VW_CustomerOrder(采用同数据表相同的命名规则,如数据表TB_Customer)的视图,选中CustomerID,CustomerName,CustomerAddress,OrderID,OrderDate字段
一个例子
添加视图的持久化类
1 namespace Wolfy.Shop.Domain.Entities 2 { 3 /// <summary> 4 /// 描述:客户订单视图持久化类 5 /// 创建人:wolfy 6 /// 创建时间:2014-11-08 7 /// </summary> 8 public class CustomerOrderView 9 { 10 /// <summary> 11 /// 客户id 12 /// </summary> 13 public virtual Guid CustomerID { get;private set; } 14 /// <summary> 15 /// 客户姓名 16 /// </summary> 17 public virtual string CustomerName { get; private set; } 18 /// <summary> 19 /// 客户住址 20 /// </summary> 21 public virtual string CustomerAddress { get; private set; } 22 /// <summary> 23 /// 订单id 24 /// </summary> 25 public virtual Guid OrderID { private set; get; } 26 /// <summary> 27 /// 下单时间 28 /// </summary> 29 public virtual DateTime OrderDate {private set; get; } 30 } 31 }
注意:对视图最常用的是查询操作,视图是一张虚表,也就是只读的(数据的来源是来自物理表的)。所以这里将持久化类的属性设置为只读的(private set)就可以了,如果真想修改数据了,就通过修改物理表的数据。
编写映射文件CustomerOrderView.hbm.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <!--assembly:程序集,namespace:命名空间--> 3 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities"> 4 <class name="Wolfy.Shop.Domain.Entities.CustomerOrderView,Wolfy.Shop.Domain" table="VW_CusomterOrder" mutable="false"> 5 <!--主键--> 6 <id name="CustomerID" type="Guid" unsaved-value="null"> 7 <column name="CustomerID" sql-type="uniqueidentifier" not-null="true" unique="true"/> 8 <generator class="assigned"></generator> 9 </id> 10 <property name="CustomerName" column ="CustomerName" type="string" 11 length="16" not-null="false" /> 12 <property name ="CustomerAddress" column="CustomerAddress" type="string" 13 length="128" not-null="false" /> 14 <property name="OrderID" column="OrderID" type="Guid" not-null="true"/> 15 <property name="OrderDate" column="OrderDate" type="DateTime" /> 16 </class> 17 </hibernate-mapping>
注意:1,在nhibernate中使用视图的时候,最容易忽略的就是没有给视图指定主键,这种情况下很容易出错。
2,注意映射文件中class节点指定mutable="false"属性(对对象的修改不能持久化到数据库中)。
3,记得添加过映射文件,修改hbm.xml属性为嵌入资源
测试
获取某客户下面所有的订单信息。
1 /// <summary> 2 /// 根据客户id查询视图,获得客户信息,及下单信息。 3 /// </summary> 4 /// <param name="guid"></param> 5 /// <returns></returns> 6 public IList<CustomerOrderView> GetCustomerOrderViewByCustomerId(Guid customerID) 7 { 8 ISession session = NHibernateHelper.GetSession(); 9 return session.CreateCriteria(typeof(CustomerOrderView)) 10 .Add(Restrictions.Eq("CustomerID", customerID)) 11 .List<CustomerOrderView>(); 12 }
此时会有一个异常
1 “NHibernate.InvalidProxyTypeException”类型的异常在 NHibernate.dll 中发生,但未在用户代码中进行处理 2 3 其他信息: The following types may not be used as proxies: 4 5 Wolfy.Shop.Domain.Entities.CustomerOrderView: method set_CustomerID should be 'public/protected virtual' or 'protected internal virtual' 6 7 Wolfy.Shop.Domain.Entities.CustomerOrderView: method set_CustomerName should be 'public/protected virtual' or 'protected internal virtual' 8 9 Wolfy.Shop.Domain.Entities.CustomerOrderView: method set_CustomerAddress should be 'public/protected virtual' or 'protected internal virtual' 10 11 Wolfy.Shop.Domain.Entities.CustomerOrderView: method set_OrderID should be 'public/protected virtual' or 'protected internal virtual' 12 13 Wolfy.Shop.Domain.Entities.CustomerOrderView: method set_OrderDate should be 'public/protected virtual' or 'protected internal virtual'
意思已经很明白了,说属性的set方法,应该是Public或者Protect virtual的。解决办法,要么修改回默认的public,要么修改映射文件的默认加载方式将hibernate-mapping的default-lazy属性设置为false。让他立即加载。
1 <?xml version="1.0" encoding="utf-8" ?> 2 <!--assembly:程序集,namespace:命名空间--> 3 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Wolfy.Shop.Domain" namespace="Wolfy.Shop.Domain.Entities" default-lazy="false"> 4 <class name="Wolfy.Shop.Domain.Entities.CustomerOrderView,Wolfy.Shop.Domain" table="VW_CusomterOrder" mutable="false"> 5 <!--主键--> 6 <id name="CustomerID" type="Guid" unsaved-value="null"> 7 <column name="CustomerID" sql-type="uniqueidentifier" not-null="true" unique="true"/> 8 <generator class="assigned"></generator> 9 </id> 10 <property name="CustomerName" column ="CustomerName" type="string" 11 length="16" not-null="false" /> 12 <property name ="CustomerAddress" column="CustomerAddress" type="string" 13 length="128" not-null="false" /> 14 <property name="OrderID" column="OrderID" type="Guid" not-null="true"/> 15 <property name="OrderDate" column="OrderDate" type="DateTime" /> 16 </class> 17 </hibernate-mapping>
异常解决参考文章:http://blog.csdn.net/sunlihgt_love/article/details/4298131
结果
生成的sql语句
总结
本文介绍了在nhibernate中使用视图的内容,遇到一个bug,将解决bug的过程分享了一下,遇到bug不要慌,解决了一个bug,你就会对它印象深刻,至少下次再遇到了,你知道如何去解决了,也是一种进步,不要怕犯错。
参考文章:http://www.cnblogs.com/lyj/archive/2008/11/01/1324201.html
-
博客地址:http://www.cnblogs.com/wolf-sun/
博客版权:如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。