Try fast search NHibernate

16 October 2010

Sharp Tests Ex 1.1.0 RTM

Sharp Tests Ex 1.1.0 RTM was released today.

Mayor changes are related to some internal matters and references to specific framework.

Now you can use SharpTestsEx even to test your Silverlight4 applications.

Download it and : Happy testing!!!

15 October 2010

ConfORMando NHibernate 3

El dia 2 de Noviembre estaré presenciando una charla en el auditorium del MUG (Microsoft Users Group) de Buenos Aires, Rivadavia 1479 1º A.


Ver mapa más grande

La intencción es la de mostrar un uso “distinto” de NHibernate.

Para asistir no se necesita ninguna experiencia previa con NHibernate y si nunca lo han usado verán cuan simple es su uso. Si ya están usando NHibernate, aunque sea desde varios años, verán algo nuevo... no creo que se vayan a aburrir.

El evento es gratuito y pueden registrarse desde aquí.
Los espero.

11 October 2010

TURBO NHibernate with domain invaders

The idea of this post have started at the local Buenos Aries CodeCap 2010 where I have attended : “In loving by Entity Framework”… well at that moment my nice girlfriend was at home. I saw a really nice girl… well… they have shown me her face and a big nice dress that covered the entire body ... I asked to see her in a bikini but it was not possible.
Seriously (I’ll try) the question to myself was: can we take some advantage, from a code generator, creating those fat POCOs ?
I know that some of my posts may seems does not have sense… to find some hidden gems in NHibernate is not so easy ;-)

Puorte 'e cazune cu nu stemma arreto...na cuppulella cu 'a visiera aizata...

public class PocoEntity
{
    public virtual Guid Id { get; set; }
    public virtual string Description { get; set; }
}

Tu vuo’ fa’ ll’americano…sient'a mme chi t' 'o ffa fa'?

public class SelfTrackingEntity : INotifyPropertyChanged
{
    private string description;
    public virtual Guid Id { get; set; }

    public virtual string Description
    {
        get { return description; }
        set
        {
            if (value != description)
            {
                description = value;
                NotifyPropertyChanged("Description");
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    private void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

Ok, I have the two entities, and now I can start the proof of concept.
I’ll fill the DataBase with one thousand instances for each entity, then I’ll upload 1000 instances of each, all in one session, I’ll modify few (only 10 entities) and then I’ll flush the session tracking the time of the flush. In other words:

[TestFixtureSetUp]
public void DbCreation()
{
    nhinit = new NHibernateInitializer();
    nhinit.Initialize();
    nhinit.CreateSchema();
    sf = nhinit.SessionFactory;
    FillDb();
}

public void FillDb()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        for (int i = 0; i < 1000; i++)
        {
            s.Persist(new PocoEntity { Description = "pocoValue" + i });
        }
        tx.Commit();
    }

    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        for (int i = 0; i < 1000; i++)
        {
            s.Persist(new SelfTrackingEntity { Description = "SelfTrackingEntityValue" + i });
        }
        tx.Commit();
    }
}

[Test]
public void TimeToFlushPocoEntities()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        var entities = s.QueryOver<PocoEntity>().List();
        var someToModify = entities.Skip(4).Take(10);
        foreach (var entity in someToModify)
        {
            entity.Description = "Modified";
        }
        var stopWath = new Stopwatch();
        stopWath.Start();
        tx.Commit();
        stopWath.Stop();
        Console.WriteLine("Milliseconds to flush and commit:" + stopWath.ElapsedMilliseconds);
    }          
}

[Test]
public void TimeToFlushSelfTrackingEntities()
{
    using (var s = sf.OpenSession())
    using (var tx = s.BeginTransaction())
    {
        var entities = s.QueryOver<SelfTrackingEntity>().List();
        var someToModify = entities.Skip(4).Take(10);
        foreach (var entity in someToModify)
        {
            entity.Description = "Modified";
        }
        var stopWath = new Stopwatch();
        stopWath.Start();
        tx.Commit();
        stopWath.Stop();
        Console.WriteLine("Milliseconds to flush and commit:" + stopWath.ElapsedMilliseconds);
    }
}

 

Tu abball' o' rocchenroll tu giochi a baisiboll... ma e solde p' e' Ccamel chi te li dá ?

The result ?

For POCO entities: 72 Milliseconds
For entities with INotifyPropertyChanged : 11 Milliseconds

The difference is really big (auto-dirty-check is 7 times slower), but the unit of measurement is not (milliseconds).

Tu vuo' fa' ll'americano ma si' nato in Italy!

How much code I wrote to have this result ?
what about this ?
  1. [Serializable]
  2. public class PostLoadEventListener : IPostLoadEventListener
  3. {
  4.     public void OnPostLoad(PostLoadEvent @event)
  5.     {
  6.         var trackableEntity = @event.Entity as INotifyPropertyChanged;
  7.         if(trackableEntity != null)
  8.         {
  9.             EntityEntry entry = @event.Session.PersistenceContext.GetEntry(@event.Entity);
  10.             entry.BackSetStatus(Status.ReadOnly);
  11.             entry.BackSetTracer(new EntityTracer(entry, trackableEntity));
  12.         }
  13.     }
  14. }
  15.  
  16. public class EntityTracer
  17. {
  18.     public EntityTracer(EntityEntry entry, INotifyPropertyChanged trackableEntity)
  19.     {
  20.         trackableEntity.PropertyChanged += (sender, e) => entry.BackSetStatus(Status.Loaded);
  21.     }
  22. }
  23.  
  24. [Serializable]
  25. public class PreDeleteEventListener : IDeleteEventListener
  26. {
  27.     public void OnDelete(DeleteEvent @event)
  28.     {
  29.         OnDelete(@event, new IdentitySet());
  30.     }
  31.  
  32.     public void OnDelete(DeleteEvent @event, ISet transientEntities)
  33.     {
  34.         var session = @event.Session;
  35.         EntityEntry entry = session.PersistenceContext.GetEntry(@event.Entity);
  36.         if (entry != null && entry.RowId is EntityTracer)
  37.         {
  38.             entry.BackSetStatus(Status.Loaded);
  39.         }
  40.     }
  41. }

 

sient' a mme: nun ce sta niente 'a fa' ok, napulitan!

This was only a proof of concept, perhaps it has memory leaks, perhaps I have used some nasty tricks… but it works.
Now is the time to apply some very little little changes in NHibernate core to allow a more easy implementation of this and others possible features.
P.S.: the sound track is available here.