我有一个SQL查询,我需要使用NHibernate的ICriteria API来表示。
SELECT u.Id as Id,
u.Login as Login,
u.FirstName as FirstName,
u.LastName as LastName,
gm.UserGroupId_FK as UserGroupId,
inner.Data1,
inner.Data2,
inner.Data3
FROM dbo.User u inner join
dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK
left join
(
SELECT
di.UserAnchorId_FK,
sum(di.Data1) as Data1,
sum(di.Data2) as Data2,
sum(di.Data3) as Data3
FROM
dbo.DailyInfo di
WHERE di.Date between '2009-04-01' and '2009-06-01'
GROUP BY di.UserAnchorId_FK
) inner ON inner.UserAnchorId_FK = u.Id
WHERE gm.UserGroupId_FK = 195
到目前为止,尝试包括映射'User'和'DailyInfo'类(我的实体)并使DailyInfo对象成为User对象的属性。但是,如何映射它们之间的外键关系仍然是一个谜,即
<one-to-one></one-to-one>
<one-to-many></one-to-many>
<generator class="foreign"><param name="property">Id</param></generator> (!)
Web上的解决方案通常与WHERE子句中的子查询有关,但是我需要在此子查询上保持连接,以确保为不连接的行返回NULL值。
我觉得我应该使用Criteria作为外部查询,然后与DetachedCriteria形成一个'join'来表示子查询?
答案 0 :(得分:1)
我遇到同样的问题,我没有得到任何解决方案。所以我用拦截器做了一个黑客
按标准生成的查询
SELECT u.Id as Id,
u.Login as Login,
u.FirstName as FirstName,
u.LastName as LastName,
gm.UserGroupId_FK as UserGroupId,
inner.Data1,
inner.Data2,
inner.Data3
FROM dbo.User u inner join
dbo.GroupMember gm on u.Id = gm.UserAnchorId_FK
InnerJoin inner ON inner.UserAnchorId_FK = u.Id
WHERE gm.UserGroupId_FK = 195
这里InnerJoin是一个与User具有1-1关系的虚拟表。 InnerJoin中的列是内连接子查询的返回值
User and InnerJoin的标准
DetachedCriteria forUser = DetachedCriteria.For<User>();
forUser.CreateCriteria("InnerJoin");
现在你可以制作拦截器来编辑查询
public interface CustomInterceptor : IInterceptor, EmptyInterceptor
{
SqlString IInterceptor.OnPrepareStatement(SqlString sql)
{
string query = sql.ToString();
if (query.Contains("InnerJoin "))
{
sql = sql.Replace("InnerJoin ", "(select [vals] form dbo.DailyInfo [where conditions])");
}
return sql;
}
}
对于包含连接子查询的多个表的返回值,您必须使用NHibernate DTO 会议就像这样
CustomInterceptor custonInterceptor=new CustomInterceptor();
sessionFactory.OpenSession(custonInterceptor);
最后的查询就像你想要的那样
答案 1 :(得分:0)
就映射关系而言,听起来你在User和DailyInfo之间有一对多的关系:
<!-- User mapping -->
<bag name="DailyInfos" inverse="true">
<key column="UserAnchorId_FK" />
<one-to-many class="Namespace.To.DailyInfo, Namespace" />
</bag>
<!-- DailyInfo mapping -->
<many-to-one name="User" column="UserAnchorId_FK" />
至于其余部分,我现在还不完全确定......听起来User
和Group
之间可能有多对多的GroupMember
表,这可能是一个复杂的因素。请记住,您可以对条件执行.CreateCriteria("Association path", jointype)
以创建具有指定连接类型的子条件。发布类/表关系的纲要可能会有所帮助。