7

我有一个名为Patient的实体对象,此实体具有Visits类型的属性,其类型为VisitsCollectionNHibernate自定义集合类型

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

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

现在我要地图,在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-agnos tic(因为它将在许多场景中使用 - 不仅与数据库一起使用)。

关于如何映射这个,保存我的代码结构的任何想法?

在此先感谢。

回答

6

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

与此不同,我的第一站就是使用扩展方法discussed by Billly McCafferty。但你有写的代码...

或者,你可以映射您的收藏作为一个组件作为discussed here by Colin Jack。这对你的情况可能更容易?

另请检查此SO thread

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?

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