Felice Pollano Blog

The Official Fatica Labs Blog

About the author

Author Name is someone.
E-mail me Send mail

Recent comments

Authors

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2008

    NHibernate Paged IBindingList

    If you want to bind a big Hibernate query result to a DataGridView in winform, you probably would like to use the SetFirstResult-SetMaxResults features avaiable in IQuery or ICriteria to achieve some kind of "paging". In winform you can chieve this by using virtual mode, but in this case you cannot deal with a DataBound grid, and the presentation code is generally worst. Another problem with paging strategy is sorting the results set. To solve this I created a very simple (abstract ) class that act as a sortable DataSource and transparently drives hibernate to fetch the records in pages. See below the class diagram:

     

     

    As you can see, to use the class you must derive one , that must implement:

    • GetTotalCount : returns the whole recordset count based on the objects you need to show
    • GetFillCriteria: returns a ICriteria based on your requirement.

    following a sample implementation class:

       12 public class JobPagedDataSource:NHibernatePagedDataSource

       13     {

       14 

       15         public JobPagedDataSource(int pageSize,ISessionFactory factory)

       16             :base(pageSize,factory)

       17         {

       18 

       19         }

       20         protected override int GetTotalCount(ISessionFactory factory)

       21         {

       22             ISession session = Factory.SessionFactory.OpenSession();

       23             IEnumerable cntEn = session.CreateQuery("select count(*) From ....").Enumerable();

       24             IEnumerator en = cntEn.GetEnumerator();

       25             en.MoveNext();

       26             session.Close();

       27             return (int)(long)en.Current;

       28         }

       29 

       30         protected override ICriteria GetFillCriteria(ISession session

       31                                                     , PropertyDescriptor sortProperty

       32                                                     , ListSortDirection direction)

       33         {

       34             ICriteria crit = session.CreateCriteria(typeof(.....));

       35             if (sortProperty != null)

       36             {

       37                 if( direction == ListSortDirection.Ascending )

       38                     crit.AddOrder( Order.Asc(sortProperty.Name));

       39                 else

       40                     crit.AddOrder( Order.Desc(sortProperty.Name));

       41             }

       42             return crit;

       43         }

       44     }

     

    If your object does not exactly fit what you need to present to the user, you will probably override the function ApplyObjectDecorator, taking as input the original "hibernated" object and returning your presenter. In this case you would probably do more check in the GetFillCriteria, to properly set the filtering properties.

    So, how to attach this to a DataGridView ? Simply do something like:

     

    MyDataGridView.DataSource = new MyImplNHibernatePagedDataSource(50,MySessionFactory);

     

    and the grid is ready to presents and sort, using a Page Size of 50 objects. For lazy objects you can experience some problem, just because the session will be closed before the datagrid use the objects, and you will have some proxy exception. There is no way out to deal with this, use eager fetch, or avoid to display the lazy columns.

     

     

    nhibernatepageddatasource.cs (6,34 kb)

    nhibernatepageddatasource.zip (1,49 kb)

    Currently rated 5.0 by 1 people

    • Currently 5/5 Stars.
    • 1
    • 2
    • 3
    • 4
    • 5

    Posted by Felice on Thursday, August 02, 2007 2:18 PM
    Permalink | Comments (3) | Post RSSRSS comment feed

    Related posts

    Comments

    Fabio Maulo ar

    Wednesday, August 15, 2007 8:45 PM

    Gravatar

    Ciao.
    Non si riesce a scaricare il source.

    Stó valutando vari paginatori; ne passo un altro che mi é sembrato interessante anche se trovo che sia un po troppo wired... fá molte cose... forse troppe, e ignora completamente l'esistenza del ResultTransformer
    http://www.codeproject.com/useritems/NHibernateDataSource.asp

    Approfitto dell'occasione per annunciare che ho da poco aperto un nuovo gruppo italiano per NHibernate.
    http://groups.google.it/group/nh-it/
    Partecipo giá attivamente al gruppo spagnolo (NHibernate-Hispano).

    Ciao.

    Tomamso Caldarola it

    Thursday, August 30, 2007 10:48 AM

    Gravatar

    Non mi piace tanto l'idea di vedere legata direttamente la session ad una classe di tipo DataSource.

    Felix it

    Thursday, August 30, 2007 4:23 PM

    Gravatar

    In effetti l'oggetto che "vedi" è la classe astratta, che non ha traccia del SessionFactory. La classe che la implementa ha traccia dei dettagli di basso livello. Con un factory il tuo applicativo rimane completamente ignaro del fatto che ci sia NHibernate in gioco.

    Add comment


    (Will show your Gravatar icon)  

      Country flag




    Live preview

    Friday, November 21, 2008 7:53 PM

    Gravatar