我收到了以下表格:
table X(CODE, FLAGGED, ENTRY_DATE)
table Y(ID, CODE)
table Z(ID, FIRST_NAME, LAST_NAME)
以下课程:
public class Xclass
{
public virtual string Code { get; set; }
public virtual bool IsFlagged { get; set; }
public virtual DateTime EntryDate { get; set; }
}
public class Yclass
{
public virtual string Id { get; set; }
public virtual string Code { get; set; }
}
public class Zclass
{
public virtual string Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
使用以下映射:
<class name="Xclass">
<id name="Code" />
<property name="IsFlagged" />
<property name="EntryDate" />
</class>
<class name="Yclass">
<id name="Id" />
<property name="Code" />
</class>
<class name="Zclass">
<id name="Id" />
<property name="FirstName" />
<property name="LastName" />
</class>
我想做以下简单查询:
SELECT X.CODE, Z.FIRST_NAME, Z.LAST_NAME
FROM X, Y, Z
WHERE X.FLAGGED = '1'
AND X.CODE = Y.CODE
AND Y.ID = Z.ID;
我是NHibernate
的新手,我读到QueryOver
,JoinAlias
/ JoinQueryOver
。
但我似乎无法找到任何指向正确方向的东西。
任何反馈将不胜感激。
答案 0 :(得分:1)
ORM通常用于建模类之间的关系,然后使用它们。在这里你没有建模任何。但是hql仍然可以执行您想要的查询:
var query = session.CreateQuery(@"
select x.Code, z.FirstName, z.LastName
from Xclass x, Yclass y, Zclass z
where x.IsFlagged = :flagged
and x.Code = y.Code
and y.Id = Z.Id")
.SetBoolean("flagged", true);
var results = query.ToList();
这将产生一个对象数组列表。如果要在类型化类中投影它们,请使用结果转换器,例如:
var results = query
.SetResultTransformer(
Transformers.AliasToBean<ADtoWithPropertiesNamedAsQueryColumnAliases>())
.List<ADtoWithPropertiesNamedAsQueryColumnAliases>();
仅在尝试执行查询时验证上述代码中的原始HQL查询。您可以使用named query在构建NHibernate会话工厂时更早地验证它。这通常可以确保您的查询在应用程序引导程序中得到验证,而不必使用代码中的原始HQL查询来测试每个功能。如果您在命名查询中出现错误,则错误的详细信息将为logged with log4net,如果您已启用它。
在你的映射下,添加:
<hibernate-mapping>
<query name="YourQueryName"><![CDATA[
select x.Code, z.FirstName, z.LastName
from Xclass x, Yclass y, Zclass z
where x.IsFlagged = :flagged
and x.Code = y.Code
and y.Id = Z.Id
]]></query>
</hibernate-mapping>
并将CreateQuery(@"...")
替换为GetNamedQuery("YourQueryName")
。
对于使用其他查询API,在大多数情况下,您必须映射表之间的关系。此处看起来您的主键上Y
和Z
之间有one-to-one。如果确实如此,请对其进行映射,然后您就可以使用queryover或linq-to-nhibernate导航关系,并从关系中选择数据。
对于Code
上的关系,您也可以对其进行映射,前提是Code
是某个表中的唯一键,可能是X
,也许是Y
,或者是另一个比如W
。在Code
唯一的表格中,最好将其映射为natural identifier。然后,在向property-ref
(以及Code
)指定column
时,向该表声明many-to-one关系,除非name
也是Code
。从该表中声明one-to-many关系,使用密钥上的property-ref
指定映射在Code
上完成(否则默认为主键)。
由于您的查询可以选择Y.Code
而不是X.Code
,并且查询api允许在where条件中使用子查询,您可以避免映射X
和Y
之间的关系使用子查询过滤Y
。