Получение прокси корректного типа в NHibernate

19
задан Stefan Steinegger 6 April 2016 в 11:05
поделиться

4 ответа

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

<class name="Animal" lazy="false">
<!-- ... -->
</class>

Как вариант, вы также можете использовать no-proxy , см. этот пост :

<property name="OwnedAnimal" lazy="no-proxy"/>

Насколько я могу видеть , он работает только тогда, когда AnimalOwner фактически является прокси.

ИЛИ

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

class AnimalOwner<TAnimal>
{
  virtual TAnimal OwnedAnimal {get;set;}
}

class CatOwner : AnimalOwner<Cat>
{
}

class DogOwner : AnimalOwner<Dog>
{
}

ИЛИ

Вы можете отобразить DogOwners и CatOwners в отдельных таблицах, и определите конкретный тип животных в отображении.

<class name="CatOwner">
  <!-- ... -->
  <property name="OwnedAninal" class="Cat"/>
</class>
<class name="DogOwner">
  <!-- ... -->
  <property name="OwnedAninal" class="Dog"/>
</class>

ИЛИ

Вы немного возитесь с NHibernate, как предложено в в этом блоге . NH на самом деле может вернуть реальный объект за прокси. Здесь немного более простая реализация, как предложено здесь:

    public static T CastEntity<T>(this object entity) where T: class
    {
        var proxy = entity as INHibernateProxy;
        if (proxy != null)
        {
            return proxy.HibernateLazyInitializer.GetImplementation() as T;
        }
        else
        {
            return entity as T;
        }
    }

, который можно использовать так:

Dog dog = dogOwner.OwnedAnimal.CastEntit<Dog>();
24
ответ дан 30 November 2019 в 03:34
поделиться

Я думаю, что у нас недавно была похожая проблема, решение AFAIR состояло в том, чтобы придать «животному» собственный метод / свойство ":

public Animal Self { get { return this; } }

Это можно затем привести к исправлению" животное ". Что происходит, так это то, что ваш исходный объект имеет ссылку на прокси-объект nhibernate (когда он лениво загружен), который действует как Animal для всех методов, предоставляемых через класс Animal (он передает все вызовы загруженному объекту). Однако его нельзя кастовать как любое другое животное, потому что оно не является ни одним из них, оно только эмулирует класс животных. Однако класс, инкапсулированный AnimalProxy, может быть приведен к классу животного с подклассами, потому что это реальный экземпляр правильного класса, вам нужно только обратиться к этой ссылке .

12
ответ дан 30 November 2019 в 03:34
поделиться

Вы могли бы хотеть попробовать это для наблюдения проксированного типа (принимающий NH 2.0 +):

((INHibernateProxy)proxy).HibernateLazyInitializer.PersistentClass

, Но этот вид кастинга или "заглядывание типа" является очень плохой практикой так или иначе...

0
ответ дан 30 November 2019 в 03:34
поделиться

Если мы работали с той же проблемой, проблема в том, что созданный прокси является прокси Animal, а не Dog.

Решение, которое мы использовали, состояло в том, чтобы перезагрузить объект:

Dog dog = this.CurrentSession.Load<Dog>(owner.OwnedAnimal.AnimalID);

Это возвращается к вашему сеансу и перезагружает объект с правильным типом.

Надеюсь, это поможет

0
ответ дан 30 November 2019 в 03:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: