在使用 NHibernate 開發專案時,多表聯查是常見需求。本文整理兩種主流解決方案,並比較優缺點。
string sql = "select oo.Orgid, go.Orgname " +
"from JkptOaxtOrganization as oo, JkptGlxtOrganization as go " +
"where oo.Orgid = " + orgid + " and oo.Suborgid = go.Orgid";
IQuery query = session.CreateQuery(sql);
IList list = query.List();
若映射檔已設定關聯,可省略 where 條件。
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Orgid", typeof(int)));
dt.Columns.Add(new DataColumn("Orgname", typeof(string)));
foreach (object[] row in list)
{
DataRow dr = dt.NewRow();
dr["Orgid"] = row[0];
dr["Orgname"] = row[1];
dt.Rows.Add(dr);
}
ds.Tables.Add(dt);
DataColumn 極其繁瑣(50 欄位需 50 行程式碼)。string sql = "select new OaxtJoinGlxt(oo.Orgid, gg.Orgname) " +
"from JkptOaxtOrganization as oo, JkptGlxtOrganization as gg " +
"where oo.Orgid = " + orgid + " and oo.Suborgid = gg.Orgid";
IList list = session.CreateQuery(sql).List();
public class OaxtJoinGlxt
{
public OaxtJoinGlxt(decimal pOrgid, string pOrgname)
{
_Orgid = pOrgid;
_Orgname = pOrgname;
}
private decimal? _Orgid;
public decimal? Orgid { get => _Orgid; set => _Orgid = value; }
private string _Orgname;
public string Orgname { get => _Orgname; set => _Orgname = value; }
}
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<import class="Model.OaxtJoinGlxt,Model"/>
<class name="Model.JkptGlxtOrganization,Model" table="JKPT_GLXT_ORGANIZATION" lazy="false">
...
</hibernate-mapping>
| 項目 | 臨時表方案 | 自訂實體方案 |
|---|---|---|
| 程式碼量 | 大(需手寫欄位) | 小(僅建構子對應) |
| 型別安全 | 弱(object[] 需轉型) | 強(強型別屬性) |
| 維護性 | 差 | 佳 |
| 效能 | 略低(多次複製) | 較高(直接投影) |
結論: 除非極簡單的臨時需求,否則強烈建議採用「select new + 自訂 DTO」方案,開發效率與執行效能雙贏。