我有以下域名模型
public interface IAppliedTo
{
public Guid Id { get; set; }
}
public class Widget
{
public DateTime DateCreated { get; set; }
public Guid Id { get; set; }
public ISet<IAppliedTo> AppliesTo { get; set; }
}
public class Master : IAppliedTo
{
public Guid Id { get; set; }
}
Widget映射将AppesTo定义为:
<set name="AppliesTo" table="WidgetAppliesTo" lazy="true" >
<key column="WidgetId"></key>
<many-to-any id-type="Guid" meta-type="int" >
<meta-value class="Master" value="1"/>
<column name="ObjectType" />
<column name="ObjectId" />
</many-to-any>
</set>
我在Master上使用QueryOver编写查询,我想为适用于Master的任何Widget提取最后一个CreatedDate。
基本上我想要这样的东西:
Master mast=null;
Widget widg=null;
var widgetQuery=QueryOver.Of<Widget>(()=>widg);
var query = NHibernateSessionManager.Instance.GetSessionFrom()
.QueryOver<Master>(() => mast)
.Where(() => mast.Name == "Josh")
.SelectList(l =>
l.SelectSubQuery(widgetQuery.Where(() => widg.AppliesTo.Contains(mast))
.Select(Projections.Max(() => widg.DateCreated))
)
);
如果我的AppliesTo是一个特定类型,我知道如何做到这一点,但我怎么能告诉nHibernate使用ObjectId。基本上我试图得到这个问题:
SELECT *,(SELECT MAX(DateCreated)
FROM Widget
INNER JOIN WidgetAppliesTo
on Widget.Id=WidgetAppliesTo.ActivityId
WHERE objectId=[master].Id)
FROM [Master]
答案 0 :(得分:1)
这可能有效,但我无法测试
Master mast=null;
var query = NHibernateSessionManager.Instance.GetSessionFrom()
.QueryOver(() => mast)
.Where(() => mast.Name == "Josh")
.SelectList(l =>
l.SelectSubQuery(QueryOver.Of<Widget>()
.JoinQueryOver(widg => widg.AppliesTo)
.Where(obj => obj.Id == mast.Id)
.Select(Projections.Max<Widget>(widg => widg.DateCreated))
)
);
答案 1 :(得分:0)
到目前为止,我设法做的最好的事情是使用Sql Projection来添加它。
.Select(Projections.SqlProjection(
"(select max(datecreated) from Widget wid
inner join WidgetAppliesTo widTo on wid.Id=widTo.ActivityId and widTo.ObjectId=this_.Id)
as lastTouchDate",
new string[]{"lastTouchDate"},
new NHibernate.Type.IType[]{NHibernateUtil.DateTime})
.WithAlias(() => jobDto.LastTouchDate));
虽然这有效但我很乐意看到一个非破解的解决方案