Проецирование подзапроса с запросом на сопоставление "многие к любому"
У меня есть следующая модель домена
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; }
}
Отображение виджета имеет AppliesTo, определенный как:
<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>
Я пишу запрос с помощью QueryOver на Master, и я хочу извлечь последнюю CreatedDate для любого виджета, который применяется к Master.
По сути, я хочу что-то вроде:
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]
2 ответа
Решение
Пока лучшее, что мне удалось сделать, - это использовать 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));
Хотя это работает, я хотел бы увидеть не взломанное решение
Это может работать, но я не могу проверить это
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))
)
);