NHibernate convert subclass to parent class

Предполагается, что следующие сущности:

public class AppUser
{
    public virtual int Id { get; set; }
    public virtual string Login { get; set; }
}

// Mapped as joined-subclass
public class Person : AppUser 
{
    public virtual int Age { get; set; }
}

Если я создаю 1 AppUser и сохраняю его следующим образом

var user = new AppUser() { Login = "test" };
session.Save( user ); // let's say Id = 1

Как я могу привести / преобразовать / «продвинуть» его в Person, сохраняя то же самое? ID?

Теперь я застрял в моей таблице AppUser со строкой с Id = N. Как я могу заполнить таблицу Person тем же Id? Я не могу удалить AppUser и воссоздать его как Person, так как на AppUser могут ссылаться внешние ключи.

Я мог бы выпустить «INSERT» SQL «вручную», но это уродливо ...

Это определенно вопрос NHibernate. Я понимаю, что с точки зрения ООП это не имеет большого смысла, отсюда и отсутствие других тегов, кроме nhibernate.

1
задан mathieu 19 August 2010 в 20:20
поделиться

2 ответа

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

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

После выполнения этой процедуры перезагрузите объект в nHibernate (и убедитесь, что вы удалили все кэшированные данные, относящиеся к нему), теперь он должен иметь правильный тип, с которым вы хотите работать, установите его НОВЫЕ свойства и сохраните его.

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

1
ответ дан 2 September 2019 в 21:59
поделиться

Это обсуждалось на SO до , и я цитирую Джона Скита для потомков:

Нет. Ссылка на производный класс должен фактически относиться к экземпляру производный класс (или null). В противном случае как вы ожидаете, что он будет вести себя?

Например:

object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?

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

В примере Скита строки - это объекты, а объекты - не строки. Так что «апкастинг» не сработает.

1
ответ дан 2 September 2019 в 21:59
поделиться
Другие вопросы по тегам:

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