8

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

VisitsCollections是的子类,IList<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

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

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

提前致谢。

4

3 回答 3

7

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

而不是这样,我的第一站是研究使用Billly McCafferty 所讨论的扩展方法。但是你有这样写的代码......

或者,您可以将您的收藏映射为Colin Jack 在此处讨论的组件。这对您的场景可能更容易?

还要检查这个SO 线程

于 2010-03-03T17:52:14.493 回答
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>

如何使用 fluentNHibernate 映射 NHibernate 自定义集合?

于 2010-07-16T09:03:41.910 回答
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
                });
        }
}
于 2017-07-31T13:14:43.383 回答