2008-11-11 6 views
6

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

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

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

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

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

ответ

4

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

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

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

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

+0

Я согласен, это имеет смысл. Я надеялся на серебряную пулю, но то, что вы упомянули, отлично подойдет. – anonymous 2008-11-12 03:22:16

2

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

Using NHibernate with Multiple Databases

Из статьи;

Введение

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

...

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

...

0

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

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

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

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

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

0

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

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

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

0

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

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+? Я еще не проследил это.

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