NHibernate聯合主鍵詳細示例

来源:http://www.cnblogs.com/cqhaibin/archive/2017/01/09/6263906.html
-Advertisement-
Play Games

使用NHibernate實現一對多,多對一的關聯很是簡單,可如果要用複合主鍵實現確實讓人有些淡淡的疼。雖然很淡疼但還是要去抹平這個坑,在下不才,願意嘗試。 以示例進入正文,源碼下載地址: 一、數據表關係圖 很明顯,他是一個自引用數表,實現無限級樹結構的存儲。 二、關鍵步驟 註解如何實現複合主鍵 根據 ...


使用NHibernate實現一對多,多對一的關聯很是簡單,可如果要用複合主鍵實現確實讓人有些淡淡的疼。雖然很淡疼但還是要去抹平這個坑,在下不才,願意嘗試。

以示例進入正文,源碼下載地址

一、數據表關係圖

很明顯,他是一個自引用數表,實現無限級樹結構的存儲。

二、關鍵步驟

  • 註解如何實現複合主鍵

根據官方文檔說明,聯合主鍵最好是一個獨立的類,需要重載Equals和GetHashCode方法,且標記為可序列化。代碼如下:

[Serializable]
public class BaseInfo
{
    public virtual string Id { get; set; }
    public virtual string GroupNumber { get; set; }

    public override bool Equals(object obj)
    {
        var baseInfo = obj as BaseInfo;
        if (baseInfo == null)
        {
            return false;
        }

        return baseInfo.Id == this.Id && baseInfo.GroupNumber == this.GroupNumber;
    }
    public override int GetHashCode()
    {
        return base.GetHashCode(); 
    }
}
  • 子類配置好聯合主鍵
[CompositeId(0, Name = "BN")]
[KeyProperty(1, Name = "Id", Column = "Id", TypeType = typeof(string))]
[KeyProperty(2, Name = "GroupNumber", Column = "GroupNumber", TypeType = typeof(string))]
public virtual BaseInfo BN { get; set; }

說明:
1.實現為引用BaseInfo類,而不是繼承.

  • 實現一對 和 多對一的映射

這步沒有多大難度,主要處理好註解的順序即可,以及OneToMany時聯合主鍵如何設置的問題.示例代碼如下:

[Bag(0, Name = "Childs", Cascade = "all", Lazy = CollectionLazy.False, Inverse = true)]
[Key(1)]
[Column(2, Name = "ParentId")]
[Column(3, Name = "GroupNumber")]
[OneToMany(4, ClassType = typeof(Foo))]
public virtual IList<Foo> Childs { get; set; }

[ManyToOne(0, Name = "Parent", ClassType = typeof(Foo))] 
[Column(1, Name = "ParentId")]
[Column(2, Name = "GroupNumber")]
public virtual Foo Parent { get; set; }

三、出錯了,有Bug

  • childs沒有數據

重載的GetHashCode方法有問題,返回值應該是聯合主鍵HashCode,優化後的實現如下:

public override int GetHashCode()
{
    return (this.Id + "|" + this.GroupNumber).GetHashCode(); //判斷緩存是否存在,已此作為Key
}
  • 插入數據時報錯,提示SqlParameterCollection的索引無效[索引溢出錯誤]

原因,最初在設計Parent的時候,與聯合主鍵共用了一個欄位GroupNumber,導致在NHibernate做映射轉換的時候會多計算出一個需要填充的值,但SqlParameterCollection中又少一個位置。優化代碼如下:

//外鍵與聯合主鍵不要共用欄位
[ManyToOne(0, Name = "Parent", ClassType = typeof(Foo))] 
[Column(1, Name = "ParentId")]
[Column(2, Name = "ParentGroupNumber")]
public virtual Foo Parent { get; set; }

說明:
1.由於聯合外鍵與聯合主鍵共用了一個欄位,導致映射出錯

四、終於實現了,總結

  • 類都必須可以序列化,也就是要還serializable標註
  • 繼承BaseInfo實現聯合主鍵(不推薦使用)

在Save時,如果用session.merge方法組合緩存與修改對象,返回值的主鍵會為Null

  • 聯合主鍵與聯合外鍵欄位不能重覆,也不能共用
  • 註意重載的GetHashCode和Equals方法
  • GetHashCode返回實例的惟一標識
  • Equals判斷是否相同實例的具體實現

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、到Apache官網下載tomcat http://tomcat.apache.org/download-80.cgi 博主我下載的是tomcat8 博主的jdk是1.8 如果你們的jdk是1.7或者1.7以下的就下載tomcat6或者tomcat7 2、把下載好的tomcat上傳到Linux虛擬 ...
  • Linux,1991年,系統安全,良好的可移植性,多用戶,多任務,良好的相容性,良好的用戶界面, 主流的是RedHat或者CentOS, CentOS 設置的網關 192.168.2.2 Windows 設置的網關 192.168.2.1 取消命令行一直運行:Ctrl+c 在命令行中切換root用戶 ...
  • 本節內容 1.github介紹 很多人都知道,Linus在1991年創建了開源的Linux,從此,Linux系統不斷發展,已經成為最大的伺服器系統軟體了。 Linus雖然創建了Linux,但Linux的壯大是靠全世界熱心的志願者參與的,這麼多人在世界各地為Linux編寫代碼,那Linux的代碼是如何 ...
  • 觀察系統當前進程的運行情況的命令是( ):A、freeB、dmesgC、topD、last 答案:http://hovertree.com/tiku/bjag/foxg5n0q.htm Linux系統通過( )命令給其他用戶發消息?A.lessB.mesg yC.writeD.echo to 答案: ...
  • nginx工作模式-->1個master+n個worker進程 安裝nginx的所需pcre庫【用於支持rewrite模塊】 下載軟體方法: 搜索 pcre download 網址:http://pcre.org 下載pcre包 wget ftp://ftp.csx.cam.ac.uk/pub/so ...
  • 1、在/etc/init.d/目錄下創建 nginx 文件,內容如下: 2.設置/etc/init.d/nginx 執行許可權 3.設置開機預設啟動 5.nginx控制命令 ...
  • 曾經六六我也是一個初級開發的實習生,當年的我初入農田,一心要做一個高產量高品質的碼農,做碼農界的袁隆平!然而,現實總是無比的殘酷,我一個剛入門的碼農,剛進農田就跌了許多跟頭。BUG天天困擾著我,不過這也是一種磨練。不然我六六也難以成為一個合格的碼農! 不過現在時代不同了,軟體公司越來越多,軟體開發行 ...
  • 委托這個東西不是很好理解,可是工作中又經常用到,你隨處可以看到它的身影,真讓人有一種又愛又恨的感覺,我相信許多人被它所困擾過。 一提到委托,如果你學過C語言,你一定會馬上聯想到函數指針。 什麼是委托?委托是C#中類型安全的,可以訂閱一個或多個具有相同簽名方法的函數指針。委托可以把函數做為參數傳遞,其 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...