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);
}
}