NHibernate 查詢語言 (HQL) 是面向對象的 SQL 方言,支援繼承、多態、關聯導航。本文系統講解五大子句基礎語法與四種參數化寫法,奠定高效查詢基礎。
from Customer c select c.Firstnamefrom Animal 可返回 Dog/Cat 實例c.Orders.elements// 簡單查詢所有
public IList<Customer> From()
=> _session.CreateQuery("from Customer").List<Customer>();
// 別名(as 可省略)
public IList<Customer> FromAlias()
=> _session.CreateQuery("from Customer as customer").List<Customer>();
// 多實體產生笛卡爾積
public IList<Object[]> Cartesian()
=> _session.CreateQuery("from Customer c, Order o").List<Object[]>();
// 單屬性返回類型化列表
public IList<int> Select()
=> _session.CreateQuery("select c.CustomerId from Customer c").List<int>();
// 多屬性返回 Object[] 數組
public IList<object[]> SelectObject()
=> _session.CreateQuery("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname")
.List<object[]>();
// 聚合函數
public IList<object[]> AggregateFunction()
=> _session.CreateQuery("select avg(c.CustomerId), sum(c.CustomerId), count(c) from Customer c")
.List<object[]>();
// DISTINCT 去重
public IList<string> Distinct()
=> _session.CreateQuery("select distinct c.Firstname from Customer c").List<string>();
public IList<Customer> Where()
=> _session.CreateQuery("from Customer c where c.Firstname = 'YJing'").List<Customer>();
支援運算符:算術(+ - * /)、比較(= >= <= <> != like)、邏輯(and or not)、字符串連接(||)、SQL 函數(upper/lower)、分組括號、in/between/is null、參數綁定(?, :name)、字面量、枚舉常量。
public IList<Customer> Orderby()
=> _session.CreateQuery("from Customer c order by c.Firstname asc, c.Lastname desc").List<Customer>();
public IList<object[]> Groupby()
=> _session.CreateQuery("select c.Firstname, count(c.Firstname) from Customer c group by c.Firstname")
.List<object[]>();
public IList<Customer> GetCustomersByFirstname(string firstname)
{
// 寫法1:字符串拼接 —— 禁用!SQL 注入風險
// return _session.CreateQuery("from Customer c where c.Firstname='" + firstname + "'").List<Customer>();
// 寫法2:位置參數 (ADO.NET 風格) —— 參數從 0 開始
// return _session.CreateQuery("from Customer c where c.Firstname=?")
// .SetString(0, firstname).List<Customer>();
// 寫法3:命名參數 —— 推薦!可讀性好、順序無關、可重複使用
return _session.CreateQuery("from Customer c where c.Firstname=:fn")
.SetString("fn", firstname).List<Customer>();
// 寫法4:命名參數列表 —— 適用 IN 查詢
// var names = new[] {"A", "B"}; .SetParameterList("names", names)
}
[Test]
public void GetCustomerByFirstnameTest()
{
var customers = _queryHQL.GetCustomersByFirstname("YJingLee");
Assert.AreEqual(1, customers.Count);
foreach (var c in customers)
Assert.AreEqual("YJingLee", c.Firstname);
}
public IList<Customer> GetCustomersWithCustomerIdGreaterThan(int customerId)
=> _session.CreateQuery("from Customer c where c.CustomerId > :cid")
.SetInt32("cid", customerId).List<Customer>();
HQL 以對象為中心,語法接近 SQL 但更強大。核心實踐原則:
distinct 解決關聯查詢重複object[] 或 DTO 投影下篇將介紹 Criteria API 動態查詢構建。