NHibernate: Получить конкретный тип ссылочной абстрактной сущности - PullRequest
5 голосов
/ 08 марта 2011

У меня есть следующие классы:

public abstract class FooBase 
{
     public virtual Guid Id { get; set; }
}

public class FooTypeA : FooBase
{
     public virtual string TypeAStuff { get; set; }
}

public class Bar
{
     public virtual Guid Id { get; set; }
     public virtual FooBase Foo { get; }
}

FooBase и FooTypeA отображаются с использованием шаблона "таблица-на-класс-иерархия". Бар отображается так:

public class BarDbMap : ClassMap<Bar>
{
     public BarDbMap()
     {
          Id(x => x.Id);
          References(x => x.Foo)
               .LazyLoad();
     }
}

Поэтому, когда я загружаю Bar, его свойство Foo является только прокси.

Как получить тип подкласса Foo (т.е. FooTypeA)?

Я прочитал много документов NH и сообщений на форуме. Они описывают способы получения этой работы для получения родительского типа, но не подкласса.

Если я попытаюсь отменить прокси класса, я получу такие ошибки, как: объект был неинициализированным прокси для FooBase

Ответы [ 3 ]

9 голосов
/ 17 марта 2011

Я выяснил, как избежать исключения, которое я получал. Вот метод, который снимает с прокси FooBase:

    public static T Unproxy<T>(this T obj, ISession session)
    {
        if (!NHibernateUtil.IsInitialized(obj))
        {
            NHibernateUtil.Initialize(obj);
        }

        if (obj is INHibernateProxy)
        {    
            return (T) session.GetSessionImplementation().PersistenceContext.Unproxy(obj);
        }
        return obj;
    }
2 голосов
/ 08 марта 2011

Добавьте свойство Self в FooBase и используйте его для проверки типа:

public abstract class FooBase 
{
    public virtual Guid Id { get; set; }

    public virtual FooBase Self { return this; }
}

Использование:

if (Bar.Foo.Self is FooTypeA) { // do something }
1 голос
/ 08 марта 2011

Чтобы получить «незафиксированный» тип, вы можете добавить такой метод в FooBase:

public virtual Type GetTypeUnproxied() {
    return GetType();
}

Когда этот метод вызывается на прокси, будет возвращен тип базового объекта.

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

Если причина для ленивой загрузки отношения Bar-> FooBase заключается в том, что FooBase (или производного типа) может содержать большие объемы данных, и вы используете NHibernate 3, вместо этого вы можете использовать lazy properties .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...