在 NHibernate 中使用自定义 SQL 加载集合
Load collection with custom SQL in NHibernate
我是 NHibernate 的新手。我了解主要概念,但现在有点卡住了:我需要使用稍微复杂的 SQL 查询来加载集合 属性。
让我解释:
我正在编写一个代码生成器,它从 Oracle 表(使用 oracle TAB 和 COL 视图)生成 classes。
所以基本上,我有两个 classes,Table 和 Column,描述如下:
public class Table
{
public virtual String Name { get; set; }
public virtual ISet<Column> Columns { get; set; }
public virtual ISet<Column> PrimaryKeys { get; set; }
}
public class Column
{
public virtual Table Table { get; set; }
public virtual String TableName { get; set; }
public virtual String Name { get; set; }
public virtual String Type{ get; set; }
public override bool Equals(object obj)
{
Column c = obj as Column;
if (obj == null)
return false;
return c.Table == Table && c.Name == Name;
}
public override int GetHashCode()
{
return (this.TableName.GetHashCode() + Name.GetHashCode()).GetHashCode();
}
}
映射 xml 文件很简单:
Table.hbm.xml :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Table" table="TAB">
<id name="Name" column="TNAME"></id>
<set name="Columns" order-by="COLNO">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"></one-to-many>
</set>
</class>
</hibernate-mapping>
Column.hbm.xml :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Column" table="COL">
<composite-id>
<key-property name="TableName" column="TNAME"></key-property>
<key-property name="Name" column="CNAME"></key-property>
</composite-id>
<property name="Type" column="COLTYPE"></property>
<many-to-one name="Table">
<column name="TNAME"></column>
</many-to-one>
</class>
</hibernate-mapping>
现在我想在 class Table 中添加一个包含主键的集合。
我可以通过以下查询获取主键列:
SELECT col.tname, col.cname, col.coltype
FROM all_constraints cons, all_cons_columns cons_cols, col
WHERE cons_cols.table_name = :MY_TABLE
and cons_cols.OWNER = :MY_ORACLE_USER
AND cons.constraint_type = 'P'
AND cons.constraint_name = cons_cols.constraint_name
AND cons.owner = cons_cols.owner
and col.tname = cons_cols.table_name
and col.cname = cons_cols.column_name
ORDER BY cons_cols.table_name, cons_cols.position
此查询的结果可以映射到我的列 class。
理想情况下,我的 Table class 现在应该是 :
public class Table
{
public virtual String Name { get; set; }
public virtual ISet<Column> Columns { get; set; }
public virtual ISet<Column> PrimaryKeys { get; set; }
}
我的问题是我看不到如何在我的 Table.hbm.xml 文件中声明此 SQL 查询。
我在文档中看到了 和 元素,但我无法让它按我想要的方式工作...
有人知道如何实现吗?
非常感谢,
妮可
嗯,终于找到问题了:)
主要是我在元素里面放了元素引起的。 NHibernate 无法在那里找到它。
所以我保持原样 Table.cs,现在我的 Table.hbm.xml 看起来如下:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Table" table="TAB">
<id name="Name" column="TNAME"></id>
<set name="Columns" order-by="COLNO">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"></one-to-many>
</set>
<set name="PrimaryKeys">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"/>
<loader query-ref="primarykeys"/>
</set>
</class>
<sql-query name="primarykeys">
<load-collection alias="col" role="Table.PrimaryKeys"/>
SELECT col.tname, col.colno, col.cname, col.coltype, col.width, col.scale, col.precision, col.nulls, col.defaultval, col.character_set_name
FROM all_constraints cons, all_cons_columns cons_cols, col
WHERE cons_cols.table_name = ?
and cons_cols.OWNER = 'MY_ORACLE_USER'
AND cons.constraint_type = 'P'
AND cons.constraint_name = cons_cols.constraint_name
AND cons.owner = cons_cols.owner
and col.tname = cons_cols.table_name
and col.cname = cons_cols.column_name
ORDER BY cons_cols.table_name, cons_cols.position
</sql-query>
</hibernate-mapping>
有效!希望对大家有帮助。
我是 NHibernate 的新手。我了解主要概念,但现在有点卡住了:我需要使用稍微复杂的 SQL 查询来加载集合 属性。 让我解释: 我正在编写一个代码生成器,它从 Oracle 表(使用 oracle TAB 和 COL 视图)生成 classes。 所以基本上,我有两个 classes,Table 和 Column,描述如下:
public class Table
{
public virtual String Name { get; set; }
public virtual ISet<Column> Columns { get; set; }
public virtual ISet<Column> PrimaryKeys { get; set; }
}
public class Column
{
public virtual Table Table { get; set; }
public virtual String TableName { get; set; }
public virtual String Name { get; set; }
public virtual String Type{ get; set; }
public override bool Equals(object obj)
{
Column c = obj as Column;
if (obj == null)
return false;
return c.Table == Table && c.Name == Name;
}
public override int GetHashCode()
{
return (this.TableName.GetHashCode() + Name.GetHashCode()).GetHashCode();
}
}
映射 xml 文件很简单:
Table.hbm.xml :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Table" table="TAB">
<id name="Name" column="TNAME"></id>
<set name="Columns" order-by="COLNO">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"></one-to-many>
</set>
</class>
</hibernate-mapping>
Column.hbm.xml :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Column" table="COL">
<composite-id>
<key-property name="TableName" column="TNAME"></key-property>
<key-property name="Name" column="CNAME"></key-property>
</composite-id>
<property name="Type" column="COLTYPE"></property>
<many-to-one name="Table">
<column name="TNAME"></column>
</many-to-one>
</class>
</hibernate-mapping>
现在我想在 class Table 中添加一个包含主键的集合。 我可以通过以下查询获取主键列:
SELECT col.tname, col.cname, col.coltype
FROM all_constraints cons, all_cons_columns cons_cols, col
WHERE cons_cols.table_name = :MY_TABLE
and cons_cols.OWNER = :MY_ORACLE_USER
AND cons.constraint_type = 'P'
AND cons.constraint_name = cons_cols.constraint_name
AND cons.owner = cons_cols.owner
and col.tname = cons_cols.table_name
and col.cname = cons_cols.column_name
ORDER BY cons_cols.table_name, cons_cols.position
此查询的结果可以映射到我的列 class。 理想情况下,我的 Table class 现在应该是 :
public class Table
{
public virtual String Name { get; set; }
public virtual ISet<Column> Columns { get; set; }
public virtual ISet<Column> PrimaryKeys { get; set; }
}
我的问题是我看不到如何在我的 Table.hbm.xml 文件中声明此 SQL 查询。
我在文档中看到了
有人知道如何实现吗?
非常感谢,
妮可
嗯,终于找到问题了:)
主要是我在
所以我保持原样 Table.cs,现在我的 Table.hbm.xml 看起来如下:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="ModelGenerator" namespace="ModelGenerator.Models">
<class name="Table" table="TAB">
<id name="Name" column="TNAME"></id>
<set name="Columns" order-by="COLNO">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"></one-to-many>
</set>
<set name="PrimaryKeys">
<key>
<column name="TNAME"></column>
</key>
<one-to-many class="Column"/>
<loader query-ref="primarykeys"/>
</set>
</class>
<sql-query name="primarykeys">
<load-collection alias="col" role="Table.PrimaryKeys"/>
SELECT col.tname, col.colno, col.cname, col.coltype, col.width, col.scale, col.precision, col.nulls, col.defaultval, col.character_set_name
FROM all_constraints cons, all_cons_columns cons_cols, col
WHERE cons_cols.table_name = ?
and cons_cols.OWNER = 'MY_ORACLE_USER'
AND cons.constraint_type = 'P'
AND cons.constraint_name = cons_cols.constraint_name
AND cons.owner = cons_cols.owner
and col.tname = cons_cols.table_name
and col.cname = cons_cols.column_name
ORDER BY cons_cols.table_name, cons_cols.position
</sql-query>
</hibernate-mapping>
有效!希望对大家有帮助。