开发者

Is there a way to override a collection's mapped order-by clause when paging in NHibernate?

开发者 https://www.devze.com 2023-04-08 07:07 出处:网络
I have an entity with a bag collection and I want to page through the entire data set. The collection has an order-by clause. When I try to eager-load the collection, NHibernate is generating SQL that

I have an entity with a bag collection and I want to page through the entire data set. The collection has an order-by clause. When I try to eager-load the collection, NHibernate is generating SQL that is very very slow because it causes SQL Server to sort on a very non-unique property, and there is a large amount of data in the table.

The code:

var session = NHibernateSessionManager.Instance.GetSession();
session.CreateCriteria<Album>()
    .SetFetchMode("Track", FetchMode.Eager)
    .SetMaxResults(1000)
    .SetFirstResult(1)
    .AddOrder(new Order("Id", true))
    .List();

The bag mapping (note the order-by attribute):

<bag name="Track" inverse="true" lazy="true" batch-size="1000" cascade="none" 
     order-by="TrackNumber ASC">

The relevant SQL generated:

OVER(ORDER BY track2_.TrackNumber, this_.Id) as __hibernate_sort_row

If i remove the order-by from the mapping then the 开发者_JS百科SQL changes to this (much better):

OVER(ORDER BY this_.Id) as __hibernate_sort_row

So the question is: is there a way to override or remove the mapped order-by clause?


After comments from Thilak Nathen and Firo, it looks like the short answer to the question is: "No you can't do that". The long answer is to remove the order-by attribute from the mapping and add it as needed. The reason it was there is that it's always needed, except for this one unusual situation. Firo suggested overriding the factory configuration which I think will work because this is for reporting. For anyone else who wants to know how to do it, here's the code to remove an order-by from an xml mapping programmatically:

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();
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号