NHibernate自定义集合类型

时间:2010-03-01 19:24:48

标签: nhibernate collections nhibernate-mapping nhibernate-collections

我有一个名为Patient的实体对象,该实体有一个名为Visits的属性,其类型为VisitsCollection

VisitsCollectionsIList<Visit>的子类,但它也为集合添加了一些自定义逻辑(如自动排序,一些验证,通知等)。

需要使用自定义集合类型,因为它会将一些数据添加到添加到集合中的实体,并透明地执行其他文书工作。

现在我想在NHibernate中映射它,所以我创建了:

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

我得到了一个例外:

  

无法将'NHibernate.Collection.PersistentList'类型的对象强制转换为'... VisitsCollection'

每当我访问访问属性时。

我也尝试过以这种方式映射:

<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>

但是,我仍然遇到这个例外:

  

自定义类型未实现UserCollectionType:..... VisitsCollection

我不想从任何NHibernate类型继承我的VisitsCollection,因为集合类是我希望它与DAL无关的框架的一部分(因为它将在许多场景中使用 - 不仅仅是用数据库)。

有关如何映射此问题的任何想法,保留了我的代码结构?

提前致谢。

3 个答案:

答案 0 :(得分:6)

我从不使用自定义集合类型,主要是因为我很懒。 NHibernate希望你使用我相信的IUserCollectionType,这需要一些管道。

而不是那样,我的第一站就是将扩展方法看作discussed by Billly McCafferty。但你有代码写的......

或者,您可以将集合映射为discussed here by Colin Jack的组件。对于您的方案,这可能更容易?

同时检查此SO thread

答案 1 :(得分:1)

我也投票决定不使用自定义集合。无论如何,你可以通过组件来做到这一点。

<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?

答案 2 :(得分:0)

仅供参考,以下是使用FluentNHibernate

执行此操作的方法

我们是否应该创建自定义集合类型是一个单独的主题恕我直言

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