使用 NHibernate AliasToBean Transformer 发起 n+1 查询

Use NHibernate AliasToBean Transformer launch n+1 query

在编辑我的问题之前,我很抱歉我的英语不好。

我有两个 类:

public class News
{
    public virtua int Id { get; set; }
    public virtual string Title { get; set; }
    public virtual string Content { get; set; }                
    public virtual LearningCenter LearningCenter { get; set; }
}

public class LearningCenter
{
    public virtua int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Address { get; set; }
    public virtual string ZipCode { get; set; }
    public virtual string PhoneNumber { get; set; }
    public virtual string Mail { get; set; }
    public virtual string DDECode { get; set; }
}    

我使用如下主代码获取新闻列表:

var query = Session
                .QueryOver<News>()
                .JoinAlias(x => x.Language, () => language, JoinType.LeftOuterJoin)
                .JoinAlias(x => x.LearningCenter, () => learningCenter, JoinType.LeftOuterJoin)
                .List<News>();

上面的代码从 NHibernate 翻译成单个 sql 查询,看起来像 "SELECT ... FROM News LEFT JOIN LearningCenter WHERE ..."

一切正常。但是我想要 select 一组字段,所以我做了类似...(注意 news 和 newsDTO 对象具有相同的类型)

News news = null;
LearningCenter learningCenter = null;
Language language = null;
News newsDTO = null;

var query = Session
                .QueryOver(() => news)
                .JoinAlias(() => news.LearningCenter, () => learningCenter, JoinType.LeftOuterJoin)
                .JoinAlias(() => news.Language, () => language, JoinType.LeftOuterJoin)
                .SelectList(l => l
                .Select(x => x.Id).WithAlias(() => newsDTO.Id)
                .Select(x => x.LearningCenter).WithAlias(() => newsDTO.LearningCenter))
                .TransformUsing(Transformers.AliasToBean<News>())
                .List<News>();

但问题是 NHibernate 将上面的代码转换为 n+1 查询,看起来像...

"SELECT ... FROM News LEFT JOIN LearningCenter WHERE..."
"SELECT ... FROM LearningCenter WHERE CenterId = 388"
"SELECT ... FROM LearningCenter WHERE CenterId = 389"
...

你知道我怎样才能让 NHibernate 将代码转换为单个查询吗?

谢谢!!!

大体上有两种方式。

1) 我们必须使用投影,并投影所有要显式选择的属性。然后我们必须使用一些更深层次的转换,例如Deep transformer here

2) 我们可以使用批量抓取,分几批加载所有相关关系。这将导致 1 + 2(4) 次查询,将所有关系加载到单独的(少数)查询中

有关投影的更多详细信息:

  • How to partially project a child object with many fields in nHibernate

有关批量提取的更多详细信息,您可以查看: