If anyone's interested, I've addressed this issue by creating 'collection wrappers' for each of IList, IDictionary and ISet collections. On instantiation, I basically copy the items into a hastable. Note that I've created an Interface iOPWObject_NHLoaded which contains a "KEY" property. This is applied to every object in my application that is loaded into a collection. Basiclly, every object 'must' expose it's own unique key, whatever that might be... 
Hope this helps someone... it seems to be working well for me. Notice that the class is abstract. I derive my own collection wrappers from one of my three 'collection' wrappers depending on me wanting a Map, List or Set. I'm instantiating 100's of 1000's of objects in my app and performance doesn't seem too bad... 
DS
Code:
using System;
using System.Collections;
namespace OPWLibrary
{
   /// <summary>
   /// A NHibernate.Collection.Bag is basically an Arraylist. You can iterate
   /// through it and can access items by index. There is however no key on
   /// it. We are forced by NH to use them because only Bags and Sets can 
   /// be used in bidirectional relationships - ie relationships where the 
   /// child can see the parent. This class will provide a wrapper for our
   /// Bags. Part of this will give a method to find a record by the key 
   /// </summary>
   abstract public class clsGenericBagWrapper : ArrayList, iOPWObject, iOPWCollection
   {
      #region Private Variables
         private Hashtable   _HashedCollection;
      #endregion
      public clsGenericBagWrapper(IList Listn) : base(List)
      {
         _application = Application;
         LoadHashedCollection();
         SaveChecksumState();
      }
      /// <summary>
      /// So that we can look up these items by their key, load them into a hashtable
      /// using their key
      /// </summary>
      /// <param name="ChildType"></param>
      private void LoadHashedCollection()
      {
         _HashedCollection = new Hashtable();
         foreach (iOPWObject_NHLoaded o in this)
         {
            _HashedCollection.Add(o.Key,o);
         }
      }
      #region iOPWCollection Members
      /// <summary>
      /// One limitation of NH is that you can't use an IDictionary in 
      /// a bidirectional relationship. You have to use a 'bag' or a 'set'. 
      /// This sort of sucks, because, if you want to look up an item by the 
      /// key, Going to try copying them into a hashtable to see if that helps.. 
      /// </summary>
      virtual public object ItemByKey(object key)
      {
            return this._HashedCollection[key];
      }
      #endregion
   }
}
I made three collection 'wrapper' base classes. For each of IList (Bag, List), IDictionary(ISet) and IMap (Map). 
I put this interface on them all.. 
Code:
namespace OPWLibrary
{
   /// <summary>
   /// Interface for each object that we use as a collection or 
   /// collection base
   /// </summary>
   public interface iOPWCollection
   {
      object ItemByKey(object key);
   }
}