NHibernate custom collection type
Asked Answered
O

3

9

I'm having an entity object called Patient and this entity is having a property called Visits which is of type VisitsCollection.

VisitsCollections is a child class of IList<Visit> but it also adds some custom logic to the collection (like auto ordering, some validation, notifications, etc..).

I need to use the custom collection type as it adds some data to the entities that are added to the collection and performs some other paperwork transparently.

Now I want to map that in NHibernate, so I've created:

<list name="Visits" lazy="true" fetch="select">
    <key foreign-key="PatientId" />
    <index column="Timestamp" />
    <one-to-many class="Visit" not-found="ignore"/>
</list>

I'm getting an exception:

Unable to cast object of type 'NHibernate.Collection.PersistentList' to type '...VisitsCollection'

Whenever I'm accessing the visits property.

I've also tried to map it this way:

<list name="Visits" lazy="true" fetch="select" collection-type="VisitsCollection">
    <key foreign-key="PatientId" />
    <index column="Timestamp" />
    <one-to-many class="Visit" not-found="ignore"/>
</list>

but still, I'm getting this exception:

Custom type does not implement UserCollectionType: .....VisitsCollection

I don't want to inherit my VisitsCollection from any NHibernate type as the collection class is part of a framework that I want it to be DAL-agnostic (as it will be used in many scenarios - not only with a database).

Any ideas on how to map this, preserving the structure of my code?

Thanks in advance.

Octans answered 1/3, 2010 at 19:24 Comment(0)
M
7

I never use custom collection types, mainly because I'm lazy. NHibernate wants you to use a IUserCollectionType I believe, which requires a bit of plumbing.

Rather than that, my first stop would be to look at using extension methods as discussed by Billly McCafferty. But you have code written so...

Alternatively, you could map your collection as a component as discussed here by Colin Jack. This might be easier for your scenario?

Also check this SO thread.

Migraine answered 3/3, 2010 at 17:52 Comment(0)
O
1

I also vote up not to use custom collections. Anyway, you can do it via component.

<component name="Warehouses" class="Core.Domain.Collections.EntitySet`1[Core.Domain.OrgStructure.IWarehouseEntity,Core],Core">
<set name="_internalCollection" table="`WAREHOUSE`" cascade="save-update" access="field" generic="true" lazy="true" >
  <key column="`WarehouseOrgId`" foreign-key="FK_OrgWarehouse" />
  <!--This is used to set the type of the collection items-->
  <one-to-many class="Domain.Model.OrgStructure.WarehouseEntity,Domain"/>
</set>

How to map NHibernate custom collection with fluentNHibernate?

Outboard answered 16/7, 2010 at 9:3 Comment(0)
A
0

Just for reference, here is how you could do it using FluentNHibernate

Whether we should or should not create a custom collection type is a separate topic IMHO

public class PatientOverride : IAutoMappingOverride<Patient>
{
        public void Override(AutoMapping<Patient> mapping)
        {
             mapping.Component(
                x => x.Visits,
                part =>
                {
                    part.HasMany(Reveal.Member<VisitsCollection, IEnumerable<Visit>>("backingFieldName")) // this is the backing field name for collection inside the VisitsCollection class
                    .KeyColumn("PatientId")
                    .Inverse(); // depends on your use case whether you need it or not
                });
        }
}
Alfonso answered 31/7, 2017 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.