我将 NHibernate 3.3.3 与 .Net 4.0 一起使用,并且面临 NHibernate 生成错误 SQL 的问题。
我有以下(简化的)课程:
class Process
{
public Customer { get; set; }
[additional properties]
}
class OrderProcess : Process
{
[further additional properties]
}
class FinishedProcess : Process
{
public DateTime SaveOn { get; set; }
}
class FinishedOrderProcess : FinishedProcess
{
[even more properties]
}
class Customer
{
public IList<OrderProcess> OrdersInProgess { get; set; }
public IList<FinisheOrderProcess> FinishedOrders { get; set;}
[additional properties]
}
使用这些类,我使用 hbm.xml 文件为 NHibernate 映射它们,方法如下:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="tadoraOrm"
namespace="tadoraOrm.Models">
<class name="Customer" table="CUSTOMER">
<id column="REC_ID" name="Id">
<generator class="identity" />
</id>
<bag name="FinishedOrders" inverse="true" cascade="none" lazy="true">
<key column="CUSTOMER_ID"/>
<one-to-many class="FinishedOrderProcess"/>
</bag>
<bag name="OrdersInProgess" inverse="true" cascade="none" lazy="true">
<key column="CUSTOMER_ID"/>
<one-to-many class="OrderProcess"/>
</bag>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="tadoraOrm"
namespace="tadoraOrm.Models">
<class name="Process" table="PROCESS" abstract="true">
<id name="Id" column="REC_ID">
<generator class="identity"/>
</id>
<joined-subclass name="FinishedProcess" table="FINISHED_PROCESS" abstract="true">
<key column="PROCESS_ID"/>
<joined-subclass name="FinishedOrderProcess" table="FINISHED_ORDER_PROCESS">
<key column="FINISHED_PROCESS_ID"/>
</joined-subclass>
</joined-subclass>
<joined-subclass name="OrderProcess" table="ORDER_PROCESS">
<key column="ORDER_PROCESS_ID"/>
</joined-subclass>
</class>
</hibernate-mapping>
最后但并非最不重要的是获取所有内容的代码(在 VB.Net 中)
Dim customers As IList(Of Customer) = session.CreateCriteria(Of Customer)().
CreateAlias("FinishedOrders", "FO").
Add(
Restrictions.Between("FO.SavedOn", dtpFrom.Value.Date, dtpUntil.Value)
).List<Customer>()
整个事情生成了这个 SQL:
select
*
from CUSTOMER C
inner join FINISHED_ORDER_PROCESS FOP
on C.REC_ID = FOP.CUSTOMER_ID
left outer join FINISHED_PROCESS FP
on FP.PROCESS_ID = FOP.FINISHED_PROCESS_ID
left outer join PROCESS P
on P.REC_ID = FP.PROCESS_ID
where FP.SavedOn between '2013-10-01T00:00:00' /* @p0 */ and '2013-10-08T17:53:50' /* @p1 */
这里的问题是 FOP 不包含列 CUSTOMER_ID 它包含在 PROCESS 表中。此外,我希望所有连接都是内连接,而不是最后两个表的左外连接。
基本上是这样的:
select
*
from CUSTOMER C
inner join FINISHED_ORDER_PROCESS FOP
on C.REC_ID = P.CUSTOMER_ID
inner join FINISHED_PROCESS FP
on FP.PROCESS_ID = FOP.FINISHED_PROCESS_ID
inner join PROCESS P
on P.REC_ID = FP.PROCESS_ID
where FP.SavedOn between '2013-10-01T00:00:00' /* @p0 */ and '2013-10-08T17:53:50' /* @p1 */
很抱歉发布了这么多代码,但我认为它以最好的方式解释了我面临的问题。
使用这种继承策略的原因是,除了以类似方式工作的订单之外,我还有几个不同的进程。
如果您知道如何使用 NHibernate Criteria API、HQL 或使用 NHibernate 的任何其他可能性来检索在指定时间范围内获得 FOP 的客户列表,如果您能分享,我将不胜感激。
如果缺少任何信息或问题似乎难以理解,请随时提问!