使用 NHibernate AliasToBean Transformer 启动 n+1 查询 [英] Use NHibernate AliasToBean Transformer launch n+1 query

查看:21
本文介绍了使用 NHibernate AliasToBean Transformer 启动 n+1 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Before edit my question I'm sorry for my poor english.

我有两个班级:

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

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

I get a list of news using a main code like:

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 ..."

The code above is translated from NHibernate to a single sql query that looks something like "SELECT ... FROM News LEFT JOIN LearningCenter WHERE ..."

一切正常.但是我想选择一组字段,所以我做了一些类似的事情......(注意新闻和新闻DTO对象具有相同的类型)

It's working fine. But I want to select a group of fields, so I make something like... (Note news and newsDTO object has same type)

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 查询,看起来像......

But the issue is NHibernate translate the code above to n+1 query that looks something like...

从新闻中选择...从左侧加入学习中心WHERE..."
选择 ... 从学习中心 WHERE CenterId = 388"
选择 ... 从学习中心 WHERE CenterId = 389"
...

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

你知道我如何为 NHibernate 将代码翻译成单个查询吗?

Do you know how can I make for NHibernate translate the code to a single query?

谢谢!!!

推荐答案

一般来说有两种方式.

1) 我们必须使用投影,并投影要明确选择的所有属性.然后我们必须使用一些更深层次的转换,例如这里是深度转换器

1) we have to use Projections, and project all properties to be selected explicitly. Then we have to use some deeper transformation e.g. Deep transformer here

2) 我们可以使用batch fetching,这将分批加载所有相关的关系.这将导致 1 + 2(4) 个查询,以在单独的(少数)查询中加载所有关系

2) we can use batch fetching, which will load all related relations in few batches. That will lead to 1 + 2(4) queries, to load all relations in separated (few) queries

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

For more details about projections:

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

For more details about batch fetching you can check this:

这篇关于使用 NHibernate AliasToBean Transformer 启动 n+1 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆