0. 前言
上一篇《C# 資料操作系列 - 11 NHibernate 配置和結構介紹》 介紹了Nhibernate裡的配置內容。這一篇將帶領大家瞭解一下如何使用NHIbernate。之前提到NHibernate繼承了Hibernate的一些傳統:使用XML檔案進行配置,這一點也是備受爭議。不過,有社群愛好者開發了一個名為《Fluent NHibernate》的專案,用來支援NHibernate的流式配置。當然,NHibernate本身也提供了NHibernate.Mapping.ByCode
模式。不過這一篇暫且略過,留待下文。
1. NHibernate對映檔案
對於NHibernate的對映檔案有個約定的名字:
<類名>.hbm.xml
這裡先為大家介紹一下對映檔案的格式:
1.1 hibernate-mapping 的說明
<hibernate-mapping
schema="schemaName" (1)
default-cascade="none|save-update" (2)
auto-import="true|false" (3)
assembly="Eg" (4)
namespace="Eg" (5)
default-access="field|property|field.camecase..." (6)
default-lazy="true|false" (7)
/>
- schema: 資料庫schema的名稱
- default-cascade:可選項,預設是none,一種預設的級聯風格
- auto-import:明確是否可以在查詢中使用非限定類名。
- assembly:指定對映物件所在的assembly,一般情況指的是專案名稱
- namespace:所在名稱空間
- default-access:可選的,預設是property,表示NHibernate的讀取資料列的策略,預設情況從Property 中讀取
- default-lazy:可選的,預設是true,是否啟動延遲載入
1.2 class的配置
一般情況下,class節點只需要指定name和table就可以了。接下來,讓我們探索class如何對映成的。
1.2.1 id
任何一個對映都必須宣告一個資料表的主鍵,大多數類也必須有一個唯一標示欄位用來區分不同的例項。
這裡介紹一下 id 節點的配置:
<id
name="PropertyName"
type="typename"
column="column_name">
<generator class="generatorClass"/>
</id>
- name : 對應的屬性名
- type:對應的NHibernate型別
- column:列名
- generator:主鍵生成器,如果不需要引數可以直接在 id節點處新增,最常用的是native。
1.2.2 property
對映一個普通屬性就簡單多了,只需要進行以下配置即可:
<property
name="propertyName"
column="column_name"
type="typename"
/>
- name :類裡的屬性名
- column:對應資料表的列名
- type:資料庫中的型別
1.2.3 many-to-one
在Nhibernate中,多對一的配置是在一的一端,表示該類有一個外來鍵導航。
<many-to-one
name="PropertyInOne"
class="ManyClass"
column="Column"
></many-to-one>
1.2.4 one-to-one
一對一的關係與多對一的關係比較相似,不同的地方在於一對一需要在雙方的對映關係裡均要維護,在有外來鍵的表/實體中 新增 constrained=“true”。
示例如下:
<one-to-one name="Person" class="Person"/>
<one-to-one name="Employee" class="Employee" constrained="true"/>
2. 增刪改查
Nhibernate的每次操作都基於一個Session,所以我們在運算元據庫的時候最好先持有一個可用的Session。接下來,我們就一個通用資料庫操作類為基礎,向大家分享一下我的想法。
首先,建立一個泛型模板類,並約束泛型為類:
public class Repository<T> where T: class
{
}
新增一個ISession屬性,用來後續訪問操作,並由構造方法賦值:
public Repository(ISession session)
{
Session = session;
}
public ISession Session { get; }
2.1 新增
現在我們寫一下新增方法:
public object Add(T entity)
{
var key= Session.Save(entity);
return key;
}
public void Add(params T[] entities)
{
foreach (var entity in entities)
{
Session.Save(entity);
}
}
查了下,Save會返回當前持久化物件插入時生成的主鍵。
2.2 修改
NHibernate的修改與EF類似,也是由ISession監控了修改,不用做過多的操作。
2.3 刪除
NHibernate的刪除也十分簡單,直接通知ISession刪除某個持久化物件。
public void Delete(T entity)
{
Session.Delete(entity);
}
public void Delete(params T[] entities)
{
foreach (var entity in entities)
{
Session.Delete(entity);
}
}
2.4 查詢
通常情況下,查詢需要結合實際業務來進行開發,當然為了通用,我在這裡選擇給呼叫方開放一個查詢物件:
public IQueryable<T> IqQueryable()
{
return Session.Query<T>();
}
其中 IQueryable是一個介面,表示這是一個可查詢物件,通過Linq可以快捷的查詢。
3. 總結
嗯,NHibernate基礎使用篇到這裡可以暫告一段落了。後續的內容有機會再深挖,當然並不代表EF Core就沒有了。嗯嗯,沒毛病。下一篇就讓我來先替大夥看看SugarSQL是什麼情況吧。
不過在本篇內容完結之前,先補充一個NHibernate的SqlDialect選值:
資料庫 | Dialect | 備註 |
---|---|---|
DB2 | NHibernate.Dialect.DB2Dialect | |
DB2 for iSeries(OS/400) | NHibernate.Dialect.DB2400Dialect | |
Firebird | NHibernate.Dialect.FirebirdDialect | 需要設定driver_class為NHibernate.Driver.FirebirdClientDriver |
Informix | NHibernate.Dialect.InformixDialect | |
Informix 9.40 | NHibernate.Dialect.InformixDialect0940 | |
Informix 10.00 | NHibernate.Dialect.InformixDialect1000 | |
Ingres | NHibernate.Dialect.IngresDialect | |
Ingres 9 | NHibernate.Dialect.Ingres9Dialect | |
Microsoft SQL Server 7 | NHibernate.Dialect.MsSql7Dialect | |
Microsoft SQL Server 2000 | NHibernate.Dialect.MsSql2000Dialect | |
Microsoft SQL Server 2005 | NHibernate.Dialect.MsSql2005Dialect | |
Microsoft SQL Server 2008 | NHibernate.Dialect.MsSql2008Dialect | |
Microsoft SQL Azure Server 2008 | NHibernate.Dialect.MsSqlAzure2008Dialect | |
Microsoft SQL Server 2012 | Hibernate.Dialect.MsSql2012Dialect | |
Microsoft SQL Server Compact Edition | NHibernate.Dialect.MsSqlCeDialect | |
Microsoft SQL Server Compact Edition 4.0 | NHibernate.Dialect.MsSqlCe40Dialect | |
MySQL 3 or 4 | NHibernate.Dialect.MySQLDialect | |
MySQL 5 | NHibernate.Dialect.MySQL5Dialect | |
MySQL 5 InnoDB | NHibernate.Dialect.MySQL5InnoDBDialect | |
MySQL 5.5 | NHibernate.Dialect.MySQL55Dialect | |
MySQL 5.5 Inno DB | NHibernate.Dialect.MySQL55InnoDBDialect | |
Oracle | NHibernate.Dialect.Oracle8iDialect | |
Oracle 9i | NHibernate.Dialect.Oracle9iDialect | |
Oracle 10g, Oracle 11g | NHibernate.Dialect.Oracle10gDialect | |
Oracle 12c | NHibernate.Dialect.Oracle12cDialect | |
PostgreSQL | NHibernate.Dialect.PostgreSQLDialect | |
PostgreSQL 8.1 | NHibernate.Dialect.PostgreSQL81Dialect | 支援8.1 的 FOR UPDATE NOWAIT |
PostgreSQL 8.2 | NHibernate.Dialect.PostgreSQL82Dialect | 在DROP TABLE和DROP SEQUENCE 語句中支援 IF EXISTS關鍵字 |
PostgreSQL 8.3 | NHibernate.Dialect.PostgreSQL83Dialect | 支援XML型別 |
SQLite | NHibernate.Dialect.SQLiteDialect | 設定driver_class為NHibernate.Driver.SQLite20Driver |
Sybase Adaptive Server Anywhere 9 | NHibernate.Dialect.SybaseASA9Dialect | |
Sybase Adaptive Server Enterprise 15 | NHibernate.Dialect.SybaseASE15Dialect | |
Sybase SQL Anywhere 10 | NHibernate.Dialect.SybaseSQLAnywhere10Dialect | |
Sybase SQL Anywhere 11 | NHibernate.Dialect.SybaseSQLAnywhere11Dialect | |
Sybase SQL Anywhere 12 | NHibernate.Dialect.SybaseSQLAnywhere12Dialect |
更多內容煩請關注我的部落格《高先生小屋》