Пользовательский тип коллекции NHibernate - PullRequest
7 голосов
/ 01 марта 2010

У меня есть объект сущности с именем Patient, а у этой сущности есть свойство с именем Visits, которое имеет тип VisitsCollection.

VisitsCollections является дочерним классом IList<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

Я не хочу наследовать VisitsCollection от какого-либо типа NHibernate, так как класс коллекции является частью структуры, и я хочу, чтобы он был независим от DAL (так как он будет использоваться во многих сценариях - не только с базы данных).

Есть идеи, как отобразить это, сохранив структуру моего кода?

Заранее спасибо.

Ответы [ 3 ]

6 голосов
/ 03 марта 2010

Я никогда не использую пользовательские типы коллекций, в основном потому, что я ленивый. NHibernate хочет, чтобы вы использовали IUserCollectionType, который, как я считаю, требует немного сантехники.

Вместо этого моей первой остановкой было бы посмотреть на использование методов расширения, как , обсуждаемое Билли МакКафферти . Но у вас есть код, написанный так ...

В качестве альтернативы, вы можете сопоставить свою коллекцию как компонент как , обсужденный здесь Колином Джеком . Это может быть проще для вашего сценария?

Также проверьте это SO thread .

1 голос
/ 16 июля 2010

Я также голосую за то, чтобы не использовать пользовательские коллекции. В любом случае, вы можете сделать это через компонент.

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

Как сопоставить пользовательскую коллекцию NHibernate с fluentNHibernate?

0 голосов
/ 31 июля 2017

Просто для справки, вот как вы могли бы сделать это, используя 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
                });
        }
}
...