【问题标题】:Projecting subquery with query-over on a many-to-any mapping在多对任意映射上使用查询来投影子查询
【发布时间】:2013-08-06 19:33:10
【问题描述】:

我有以下领域模型

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; }
}

小部件映射已将 ApplysTo 定义为:

<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]

【问题讨论】:

  • 差不多一年后,我正在追踪本节中的一个错误并尝试找出子查询的方法..低,我在谷歌搜索的顶部找到了这个.. .time 赏金

标签: nhibernate queryover


【解决方案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))
        )
    );

【讨论】:

    【解决方案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));
    

    虽然这可行,但我希望看到一个非黑客解决方案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 2018-09-18
      • 1970-01-01
      • 2020-12-19
      相关资源
      最近更新 更多