Yeah, this is because it treats CustomCollectionType like
CollectionType in this respect.  The CustomCollectionType doesn't
override the GetElementsCollection from it's base CollectionType.  And
even if it did, what would it do?  It wouldn't know what to return for
custom collections.  I think the correct fix is to have
IUserCollectionType expose the GetElementsCollection on its
interface.  Then the CollectionType or CustomCollectionType would
implement GetElementsCollection by delegating it to the actual
IUserCollectionType.  The IUserCollectionType is the only one that
properly knows what the elements are.  This delegation happens for
almost every other method in CustomCollectionType.

In lieu of the above "proper" fix, I tried another fix where
CustomCollectionType overrides the GetElementsCollection and just
checks if the collection is an IDictionary and if so it returns the
Values from the Dictionary (just like MapType does).  If it's not a
dictionary, then it just reverts to the base class behavior.

Here's the code I added:

NHibernate\1.2\src\NHibernate\Type\CustomCollectionType.cs

      /// <summary>
      /// Returns a reference to the elements in the collection.
      /// </summary>
      /// <param name="collection">The object that holds the
ICollection.</param>
      /// <returns>An ICollection of the Elements(classes) in the
Collection.</returns>
      /// <remarks>
      /// By default the parameter <c>collection</c> is just cast to
an ICollection. Collections
      /// such as Maps and Sets should override this so that the
Elements are returned - not a
      /// DictionaryEntry.
      /// </remarks>
      public override ICollection GetElementsCollection(object
collection)
      {
         // See documentation above about how the dictionary values
have to be returned here.
         if (collection is IDictionary)
         {
            return ((IDictionary)collection).Values;
         }
         return base.GetElementsCollection(collection);
      }

This change seems to allow me to persist custom dictionaries just fine
now.  (I didn't change this in the NHibernate source repository, just
on my local machine).

Jon.


On Sep 7, 6:07 pm, srf <[EMAIL PROTECTED]> wrote:
> We are on nhibernate 1.2 and have been able to implement our own
> custom list collections but when we tried to implement a custom
> dictionary collection we get the following error:
>
> "Unknown entity class: System.Collections.Generic.KeyValuePair`2
>
> I debugged into it and found when using a custom dictionary it uses
> the base CollectionType class for the dictionary collection and the
> framework ends up call this method in this class:
>
> public virtual ICollection GetElementsCollection(object collection)
>                 {
>                         return ((ICollection) collection);
>                 }
>
> I then debugged it using the standard dictionary and it ended up using
> the MapType class which inherits CollectionType and its method looks
> like this:
>
> public override ICollection GetElementsCollection(object collection)
>                 {
>                         return ((IDictionary) collection).Values;
>                 }
>
> notice the first one returns the collection which is why the error
> about unknow entity class is being raised since it ends up returning a
> collection of key value pairs rather than a collection of objects as
> what the MapType class does.
> So , I how can we somehow get it to use the MapType class since using
> a custom type always forces the use of the CollectionType class. If
> anyone has an example of doing a custom dictionary collection , that
> would be great too.
>
> thanks
>
> scott

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to