NHibernate: один базовый класс, несколько отображений - PullRequest
6 голосов
/ 11 ноября 2008

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

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

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

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

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

Ответы [ 5 ]

4 голосов
/ 12 ноября 2008

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

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

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

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

2 голосов
/ 12 ноября 2008

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

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

Из статьи;

Введение

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

...

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

...

0 голосов
/ 15 ноября 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 использовать сопоставление интерфейса? Или мне придется объявлять пустые подкадры в сопоставлении для каждого класса, реализующего интерфейс отображение?)

0 голосов
/ 15 ноября 2008

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

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

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

0 голосов
/ 15 ноября 2008

Я не уверен на 100%, что это будет делать то, что мне нужно, но сегодня я обнаружил, что гугл по поводу 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 с наследованием, но я думаю, что это сделает ограниченное, что я хочу.

...