目錄
寫在前面
前面的文章主要講了對物理數據表的操作,當然了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
