使用 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
有关批量提取的更多详细信息,您可以查看:
- 文档 - http://nhibernate.info/doc/nh/en/index.html#performance-fetching-batch
- How to Eager Load Associations without duplication in NHibernate? 或
- NHibernate: Select one to Many Left Join - Take X latest from Parent
在编辑我的问题之前,我很抱歉我的英语不好。
我有两个 类:
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
有关批量提取的更多详细信息,您可以查看:
- 文档 - http://nhibernate.info/doc/nh/en/index.html#performance-fetching-batch
- How to Eager Load Associations without duplication in NHibernate? 或
- NHibernate: Select one to Many Left Join - Take X latest from Parent