我有一个包含包集合的实体,我想对整个数据集进行分页。该集合有一个 order-by 子句。当我尝试急切加载集合时,NHibernate 生成的 SQL 非常非常慢,因为它会导致 SQL Server 根据非常不唯一的属性进行排序,并且表中存在大量数据。
代码:
var session = NHibernateSessionManager.Instance.GetSession();
session.CreateCriteria<Album>()
.SetFetchMode("Track", FetchMode.Eager)
.SetMaxResults(1000)
.SetFirstResult(1)
.AddOrder(new Order("Id", true))
.List();
bag 映射(注意 order-by 属性):
<bag name="Track" inverse="true" lazy="true" batch-size="1000" cascade="none"
order-by="TrackNumber ASC">
生成的相关SQL:
OVER(ORDER BY track2_.TrackNumber, this_.Id) as __hibernate_sort_row
如果我从映射中删除 order-by,那么 SQL 就会更改为这样(好多了):
OVER(ORDER BY this_.Id) as __hibernate_sort_row
所以问题是:有没有办法覆盖或删除映射的 order-by 子句?
经过 Thilak Nathen 和 Firo 的评论,问题的简短答案似乎是:“不,你不能那样做”。长答案是从映射中删除 order-by 属性并根据需要添加它。它存在的原因是它总是需要的,除了这种不寻常的情况。 Firo 建议覆盖工厂配置,我认为这会起作用,因为这是用于报告。对于其他想知道如何操作的人,以下是以编程方式从 xml 映射中删除 order-by 的代码:
Configuration cfg = new Configuration().Configure();
var albumMapping = cfg.ClassMappings.Where(x => x.DiscriminatorValue == "Foo.Album").First();
var trackProperty = albumMapping.GetProperty("Track");
var bagMapping = ((NHibernate.Mapping.Bag)trackProperty.Value);
bagMapping.OrderBy = "";
sessionFactory = cfg.BuildSessionFactory();