NHibernate: один базовый класс, несколько сопоставлений

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

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

Проблема в том, что я понятия не имею, как заставить NHIbernate использовать определенный файл сопоставления для объекта. Приведение унаследованного класса к базовому классу ничего не дает при использовании session.save () (он жалуется на отсутствие сопоставления).

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

Все вещи о наследовании, которые я смог найти в отношении NHibernate (глава 8), не кажутся полностью применимыми к этой функции, но я могу ошибаться (таблица для каждого конкретного класса выглядит полезной, но я могу '' Я полностью обдумываю, как NHibernate понимает, что делать).


person anonymous    schedule 11.11.2008    source источник


Ответы (5)


Не знаю, поможет ли это, но в принципе я бы не стал этого делать.

По сути, я думаю, что вы, возможно, страдаете синдромом «золотого молотка»: когда у вас ДЕЙСТВИТЕЛЬНО хороший молоток (например, Hibernate (и я разделяю ваше мнение о нем; это ВЕЛИКОЛЕПНЫЙ инструмент)), все выглядит как гвоздь.

Обычно я бы попытался просто иметь класс «ручного преобразования», то есть такой, у которого есть конструкторы, которые принимают классы гибернации для ваших индивидуальных серийных классов и который просто копирует данные в свой собственный конкретный формат; тогда Hibernate может просто сериализовать его в (единую) базу данных, используя собственное отображение.

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

person Paul Sonier    schedule 12.11.2008
comment
Да, я согласен, это имеет смысл. Я надеялся на серебряную пулю, но то, что вы упомянули, отлично подойдет. - person anonymous; 12.11.2008

Это может помочь;

Использование NHibernate с несколькими базами данных

Из статьи;

Введение

... описано с использованием NHibernate с ASP.NET; он предлагал рекомендации по взаимодействию с единой базой данных. Но иногда необходимо взаимодействовать с несколькими базами данных одновременно. Чтобы NHibernate сделал это, должна существовать фабрика сеансов для каждой базы данных, с которой вы будете взаимодействовать. Но, как это часто бывает с несколькими базами данных, некоторые из них используются редко. Поэтому может быть хорошей идеей не создавать фабрики сеансов до тех пор, пока они действительно не понадобятся. Эта статья продолжается с того места, где закончилась предыдущая статья NHibernate с ASP.NET, и описывает детали реализации этого простого подхода. Хотя предыдущая статья была посвящена ASP.NET, приведенное ниже предложение поддерживается как в ASP.NET, так и в .NET.

...

Первое, что нужно сделать при работе с несколькими базами данных, - это настроить правильную связь. Создайте отдельный файл конфигурации для каждой базы данных, поместите их все в центральную папку конфигурации, а затем укажите на них ссылку в файле web / app.config.

...

person Nelson Miranda    schedule 12.11.2008

Я не уверен на 100%, что это сделает то, что мне нужно, но сегодня я нашел этот поиск в Google о NHibernate и анонимных типах:

http://infozerk.com/averyblog/refactoring-using-object-constructors-in-hql-with-nhibernate/

Интересная часть (для меня я новичок в этом) - это ключевое слово 'new' в предложении выбора HQL. Итак, что я мог сделать, так это выбрать SerialX из DatabaseX с помощью mappingX и передать его конструктору для SerialY (общий / базовый Serial). Итак, теперь у меня есть SerialY, сгенерированный из mappingX / databaseX, и (надеюсь) я мог бы тогда session.save, а NHibernate будет использовать mappingY / databaseY.

Причина, по которой мне это нравится, просто в том, что у меня нет двух классов с одинаковыми данными (я думаю!). На самом деле нет функциональной разницы между этим и возвращением списка SerialX, повторением его и генерацией SerialY и добавлением его в новый список (полученный первый и лучший ответ).

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

person anonymous    schedule 14.11.2008

Хотя это правда, что вам понадобится файл / класс сопоставления для каждой из этих таблиц, ничто не мешает вам заставить все эти классы реализовать общий интерфейс.

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

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

person Community    schedule 14.11.2008

Я написал очень длинный пост с кодом и всем остальным, чтобы ответить Дэну. В итоге, думаю, я упустил очевидное.

public class Serial
{
    public string SerialNumber {get; set;}
    public string ItemNumber {get; set;}
    public string OrderNumber {get; set;}
}

...

Serial serial = sessionX.get(typeof(Serial), someID);
sessionY.save(serial);

NHibernate должен использовать mappingX для получения и mappingY для сохранения, поскольку сеансы не используются совместно, а отображение привязано к сеансу. Таким образом, у меня может быть 2 сопоставления, указывающих на один и тот же класс, потому что в любом конкретном сеансе существует только одно сопоставление с отношением классов.

По крайней мере, я так думаю (не могу проверить банкомат).

К сожалению, этот конкретный случай действительно скучен и бесполезен. В другой программе того же домена я получаю от базового класса определенную часть бизнес-логики. Я не хотел создавать файл сопоставления, потому что это было просто для облегчения небольшого фрагмента кода. В любом случае, я не смог заставить его работать в NHibernate по тем же причинам, что и мой первый вопрос, и применил метод, описанный McWafflestix, чтобы обойти это (поскольку это было второстепенным).

Тем не менее, я нашел это через Google:

http://jira.nhibernate.org/browse/NH-662

Это точно такая же ситуация, и она, кажется (возможно) решена в NH 2.1+? Я еще не следил за этим.

(примечание: Дэн, в моем случае я получаю от нескольких баз данных, пишу только в один. Мне все еще интересно ваше предложение об интерфейсе, потому что я думаю, что это хорошая идея для других случаев. Не могли бы вы определить сопоставление с Если я попытаюсь сохранить класс, реализующий интерфейс, не имеющий определения сопоставления, будет ли NHibernate использовать сопоставление интерфейса? Или мне придется объявлять пустые подклассы в сопоставлении для каждого класса, реализующего сопоставление интерфейса?)

person anonymous    schedule 15.11.2008