The official Fatica Labs Blog! RSS 2.0
# Wednesday, August 08, 2007
La versione ufficiale di Castle ActiveRecord non supporta NHibernate 1.2. Per poter utilizzare active record bisogna scaricare il trunk di castle, ma a me il link svn pubblicato per qualche motivo non funziona. In alternativa il trunk si può scaricare dal build server disponibile in http.
Wednesday, August 08, 2007 9:44:00 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback

# Thursday, August 02, 2007

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)

Thursday, August 02, 2007 1:18:00 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback

# Tuesday, July 31, 2007

E' un po' che uso questa strategia, soprattutto perchè mi piace il componente propertygrid, che permette di editare le proprietà pubbliche di un oggetto.  Se una delle proprietà è un enum, viene graziosamente presentato un combobox per scegliere il valore possibile. Tuttavia le scritte presentate sono i nomi interni dell'enum, che possono essere un po' criptici per l'utente finale, e peggio a volte devono essere tradotti. Visto che non si può derivare una classe da un enum per fare l'override di ToString(), una ( possibile ) soluzione è quella di utilizzare un TypeConverter

xes: 

    [TypeConverter(typeof(SheetForecastingEnumConverter))]
    public enum SheetForecastingEnum
    {
        None,
        Auto,
        UserSelection
    }

 

quindi si implementa la classe del converter: 

 

class SheetForecastingEnumConverter : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                switch (value)
                {
                    case "None":
                        return SheetForecastingEnum.None;
                   ........ // altri case per i vari valori
                }
            }
            return base.ConvertFrom(context, culture, value);
        }
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            //show combobox
            return true;
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            //show non editable combobox
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection
                (
                    new SheetForecastingEnum[] { SheetForecastingEnum.Auto, SheetForecastingEnum.None, SheetForecastingEnum.UserSelection }
                );
        }
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string) && value != null)
            {

                SheetForecastingEnum ct = (SheetForecastingEnum)value;
                switch (ct)
                {
                    case SheetForecastingEnum.None:
                        return "Nessuno";

                    ......
                  
                    default:
                        return "?";

                }
            }
            else
                return base.ConvertTo(context, culture, value, destinationType);
        }
    }

ed il gioco è fatto. 

Tuesday, July 31, 2007 4:58:00 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback

# Friday, July 27, 2007

Un interessante catalogo di antipattern. Chi non ne ha collezionato almeno uno scagli la prima pietra.  Al momento sono in forte battaglia per evitare la Analysis Paralysis, ed anche se sto combattendo con un gigante sono convinto che, in qualche modo, me la caverò.  Per certo invece riuscirò sempre ad evitare l' Architets Don't Code, perchè forse non sarò un bravo architetto, ma a smettere di scrivere codice non ci riesco.

 

Friday, July 27, 2007 2:01:00 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback

# Wednesday, July 25, 2007

Sorry for all the people using it. At the moment I have no more time to mantain Deblector. I cannot release it as an Open Source project because the code is still messy. May be this will change in the future, but at the moment no promises.

 

Wednesday, July 25, 2007 8:00:00 AM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback
Cose che non riesco a finire
# Friday, July 20, 2007

Come back soon....

 

Er Fatica è stanco...

Friday, July 20, 2007 10:09:00 PM (GMT Daylight Time, UTC+01:00)  #    Comments [0] - Trackback

Archive
<August 2007>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678
About the author/Disclaimer

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

© Copyright 2010
Felice Pollano
Sign In
Statistics
Total Posts: 67
This Year: 41
This Month: 2
This Week: 0
Comments: 36
This blog visits
Locations of visitors to this page
All Content © 2010, Felice Pollano
DasBlog theme 'Business' created by Christoph De Baene (delarou) and modified by Felice Pollano