首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Castle ActiveRecord 實戰(7):HQL 查詢全攻略——SimpleQuery、ScalarQuery、自定義查詢與 Callback 模式

     編輯:關於.NET

HQL 核心語法速查

HQL (Hibernate Query Language) 是面向物件的查詢語言,操作的是實體與屬性而非資料表欄位。

子句範例說明
FROMfrom Post / from Post p查詢實體,可起別名
SELECTselect p.Title, p.Author from Post p投影查詢,回傳陣列或 Tuple
集合查詢select elements(blog.Posts) from Blog blogelements() 展開集合
聚合函數select count(*) from Blog / select max(p.Price) from Product p支援 count, sum, avg, min, max, count(distinct ...)
WHEREfrom Blog b where b.Author = 'Terry'支援參數綁定 ? 或命名參數 :name

查詢方式一:SimpleQuery——最直觀的 HQL 執行器

適用於回傳實體集合或標量陣列,支援位置參數 ?:

public static Post[] GetPostsByCategory(string category) {
    var query = new SimpleQuery(typeof(Post), 
        "from Post post where post.Category = ?", category);
    return (Post[])ActiveRecordBase.ExecuteQuery(query);
}

public static int[] GetPostIdsByDateRange(DateTime start, DateTime end) {
    var query = new SimpleQuery(typeof(Post), typeof(int),
        "select post.Id from Post post where post.Created between ? and ?", start, end);
    return (int[])ActiveRecordBase.ExecuteQuery(query);
}

關鍵點:第二個建構子參數 typeof(int) 指定回傳標量型別,否則預設回傳實體型別。

查詢方式二:ScalarQuery——單一標量值查詢

專為 count、sum 等聚合查詢設計,直接回傳單一值:

public static int GetPostCountByAuthor(string author) {
    var query = new ScalarQuery(typeof(Blog),
        "select count(elements(blog.Posts)) from Blog blog where blog.Author = ?", author);
    return (int)ActiveRecordBase.ExecuteQuery(query);
}

查詢方式三:自定義查詢——完全掌控 NHibernate Session

繼承 ActiveRecordBaseQuery 覆寫 Execute(ISession session),適合複雜參數邏輯、分頁、動態 HQL:

public class BlogQuery : ActiveRecordBaseQuery {
    public string AuthorName { get; set; }
    public int MaxResults { get; set; } = 10;

    public BlogQuery() : base(typeof(Blog)) { }

    public override object Execute(ISession session) {
        var hql = "from Blog blog";
        if (!string.IsNullOrEmpty(AuthorName)) hql += " where blog.Author = :author";

        var q = session.CreateQuery(hql);
        if (!string.IsNullOrEmpty(AuthorName)) q.SetString("author", AuthorName);
        q.SetMaxResults(MaxResults);

        return base.GetResultsArray(typeof(Blog), q.List(), null, false);
    }
}

// 使用
public static Blog[] GetBlogsByAuthor(string author, int max = 10) {
    var q = new BlogQuery { AuthorName = author, MaxResults = max };
    return (Blog[])ActiveRecordBase.ExecuteQuery(q);
}

查詢方式四:NHibernateDelegate Callback——輕量級 Session 操作

無需額外類別,直接傳遞委派處理 ISession:

public static Blog[] GetBlogsByAuthorCallback(string author) {
    return (Blog[])ActiveRecordBase.Execute(typeof(Blog), 
        new NHibernateDelegate(GetBlogsCallback), author);
}

private static object GetBlogsCallback(ISession session, object instance) {
    var author = (string)instance;
    var query = session.CreateQuery("from Blog blog where blog.Author = :author");
    query.SetString("author", author);
    var results = query.List();
    var blogs = new Blog[results.Count];
    results.CopyTo(blogs, 0);
    return blogs;
}

效能與選型建議

場景推薦方式理由
簡單實體集合查詢SimpleQuery語法簡潔,自動映射實體
聚合/單一值查詢ScalarQuery專為標量優化,回傳型別明確
動態 HQL、分頁、複雜參數自定義查詢類別可複用、可測試、支援完整 Session API
一次性邏輯、不想增加類別Callback 委派輕量、內聯,適合簡單臨時查詢

進階技巧:命名參數 vs 位置參數

  • 位置參數 ?:SimpleQuery 預設,順序對應,簡單但易因順序錯誤導致 Bug。
  • 命名參數 :name:自定義查詢/Callback 中使用 q.SetString("name", val),可讀性高、順序無關、支援重複參數。

總結

ActiveRecord 提供四種 HQL 查詢進階方式,從簡單到複雜層層遞進。掌握各自適用場景,配合命名參數與自定義查詢類別,能優雅解決 95% 以上的複雜查詢需求,同時保持程式碼可測試與可維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved