NHibernate QueryOver子查询

标签 nhibernate queryover

我看过类似的问题,但找不到简单的解释。我本来可以错过的,但是我保证我已经看过了。实际上,除了一个博客文章,我什至找不到任何文档,该博客文章迅速介绍了所有内容,并假定您熟悉其他形式的NH。

给定ProgramTopic之间的多对多关系,后者位于Topics层次结构中,我想检索给定Programs的所有Topic,可能包括其子主题。由于一个程序可能会在给定父主题的多个子主题下列出,因此我需要使用子查询或必须使用不同的子查询(而TransformUsing(Transformers.DistinctRootEntity)的简单方法行不通)。

原始SQL应该是这样的

SELECT ProgramId, Title, bar, baz, foo FROM Programs 
WHERE ProgramId IN 
 (SELECT ProgramId from Program_Topics WHERE TopicId IN (1, 2, ...))

结果将转换为模型类型以传输到 View 。我最初的尝试是这样的:
ProgramDTO pDTO = null;

/* topicIds is List<int> passed into function */

var query = Session.QueryOver<Program>()
.JoinQueryOver<Topic>(p => p.Topics)
.WhereRestrictionOn(pt => pt.Id).IsInG<int>(topicIds)     
.TransformUsing(Transformers.DistinctRootEntity)
.SelectList(list => list
        .Select(program => program.Id).WithAlias(() => pDTO.Id)
        .Select(program => program.Title).WithAlias(() => pDTO.Title)
        .Select(program => program.Location).WithAlias(() => pDTO.Location)
        .Select(program => program.Description).WithAlias(() => pDTO.Description)
)
.TransformUsing(Transformers.AliasToBean(typeof(ProgramDTO)));

return query.List<ProgramDTO>();    

显然,这会运行联接而不是子查询,但是我找不到像这样使用多对多子查询的示例。
public class Program : Entity {
    public virtual ISet<Topic> Topics { get; protected internal set; }
     ...
}

public class Topic : Entity {
    public virtual ISet<Program> Programs { get; protected internal set; }
    public virtual Topic ParentTopic { get; protected internal set; }
    ...
}

最佳答案

您需要创建一个包含ID的独立查询,然后将此子查询与主查询一起使用。

我在这里粘贴了一个示例,因此您将需要用类名等替换相关的位。

首先进行设置(您可以忽略此位):-

public class TestDto {
  public long Id { get; set; }
  public string Name { get; set; }
}
...
TestDto dto = null;
var ids = new List<int> { 1,2,5,7 };

现在分离查询:
var idSubQuery = QueryOver.Of<CmsRegionContent>()
  .WhereRestrictionOn(w => w.Id).IsIn(ids)
  .Select(Projections.Distinct(Projections.Property<CmsPage>(s => s.Id)));

最后一点是将所有内容放在一起:
var query = Session.QueryOver<CmsPage>()
    .JoinQueryOver<CmsRegionContent>(l => l.CmsRegionContentList)
    .WithSubquery
    .WhereProperty(m => m.Id)
    .In(idSubQuery)
    .SelectList(list => list
                            .Select(p => p.Id).WithAlias(() => dto.Id)
                            .Select(p => p.PageName).WithAlias(() => dto.Name)
                )
                .TransformUsing(Transformers.AliasToBean(typeof(TestDto)));

var model = query.List<TestDto>();

这将创建以下SQL:-
SELECT
     this_.Id as y0_,
     this_.PageName as y1_ 
FROM cmspage this_ inner join cmsregioncontent cmsregionc1_ 
  on this_.Id=cmsregionc1_.PageId 
WHERE cmsregionc1_.Id in (
    SELECT
         distinct this_0_.Id as y0_ 
    FROM cmsregioncontent this_0_ 
    WHERE this_0_.Id in (
        1 /* ?p0 */,
         2 /* ?p1 */,
         5 /* ?p2 */,
         7 /* ?p3 */)
    )

希望您能够在此之后加上您的类(class)/属性(property)名称。

关于NHibernate QueryOver子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9284700/

相关文章:

c# - 如何处理 NHiberate 用户类型中的属性延迟加载

nhibernate - ASP.NET MVC 2 RC 模型与 NHibernate 和下拉列表绑定(bind)

nhibernate - 使用 nhibernate(和 queryover)急切地获取多个嵌套关联

c# - 如何将属性值转换合并到 NHibernate QueryOver .SelectList 中?

.net - NHibernate 中的延迟初始化

c# - NHibernate 加载具有部分子集合的实体

c# - NHibernate关于多对多关系的一些属性的搜索

c# - 带左自连接的 NHibernate QueryOver

nhibernate - NHibernate/Hibernate HQL 和 ICriteria 查询示例在哪里?

c# - Fluent Nhibernate - 通过分组连接查询