Отображение NHibernate: сохранение иерархии в одной таблице без дискриминатора - PullRequest
3 голосов
/ 17 декабря 2010

У меня очень расширяемое и модульное приложение. Я хочу расширить сопоставленные Entites из других сборок. Тем не менее, мне все еще нужно работать с базовыми классами.

Пример:

Отображение родительского класса в сборке A:

    public class PersonMap : ClassMap<Person> 
    {
        public PersonMap()
        {
            Table("Persons");

            Id(x => x.Id).GeneratedBy.Assigned();
        }
}

Отображение дочернего класса в сборке B:

public class EmployeeMap : SubclassMap<Employee>
{
    public EmployeeMap()
    {
        Table("Persons");
        Extends(typeof(Person));

        KeyColumn("Id");

        LazyLoad();

        HasMany<Assignments>(x => x.Assignments).KeyColumn("Id").Inverse().Cascade.AllDeleteOrphan().LazyLoad().NotFound.Ignore();
    }
}

Теперь, когда я создаю Person в каком-то коде сборки A, он сохраняется как Employee в NHibernate. И это приводит к исключению приведения класса из-за того, что каждый раз, когда я сохраняю Person, пытаюсь обновить его в сборке A. Я не должен зависеть от Assembly B.

Мне нужно работать с родительским классом во всех методах сборки A. Дочерний класс используется только в других сборках.

Как я могу сопоставить что-то подобное? Как я могу сказать NHibernate просто сохранить его как родительский класс? Я использую SaveOrUpdate для сохранения сущностей; Как правильно расширить сущности и в то же время сохранить их в одной таблице без дискриминатора? Не можете NHibernate дифференцировать по типу объекта? Есть ли обходной путь?

Я не хочу указывать прокси-серверы вручную, так как мне пришлось бы создавать прокси для каждой сущности! Я не могу использовать шаблон посетителя из-за проблем с зависимостями.

Мне нужен способ расширить сопоставленную сущность в другой сборке без таких проблем! База данных является устаревшей, я не могу ее изменить. Как бы вы обойти эту проблему?

Ответы [ 2 ]

0 голосов
/ 20 апреля 2011

Решено с помощью сопоставления HasOne для той же таблицы и без использования подкласса. Это не дает идеального кода, но без проблем.

0 голосов
/ 17 декабря 2010

Ваша цель отображения иерархии в одной таблице без дискриминатора представляет собой головоломку. На уровне данных должно быть что-то, что дает DAL подсказку о том, что конкретная запись является Сотрудником, а не просто Человеком. Поскольку вы не сопоставляете какие-либо дополнительные поля в таблице Persons для Employee и не предоставляете дискриминатор, в отдельной записи таблицы Persons нет ничего, что отличало бы Person от более производных сотрудников.

Не могли бы вы предоставить код, который вы используете для получения записей Person? По моему опыту, запросы NHibernate практически всегда требуют типа домена для гидратации. Может случиться так, что в этом случае NHibernate пытается создать объекты наиболее производного типа, который он знает, и поскольку он не может отличить базового сотрудника от более производного сотрудника, все сотрудники являются сотрудниками. Вы можете попробовать Linq, который вызывает строго типизированную гидратацию объектов, в отличие от HQL или других менее жестких ссылок.

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