(N)Hibernate - возможно ли динамически сопоставить несколько таблиц с одним классом
-
09-06-2019 - |
Вопрос
У меня есть ситуация, когда я использую программное обеспечение ГИС, которое хранит информацию об объектах ГИС в отдельной таблице базы данных для каждого типа/класса объекта ГИС (дорога, река, здание, море,...) и сохраняет таблицу метаданных, в которой она хранится. информация об имени класса и его таблице БД.
Эти ГИС-объекты разных классов имеют общие параметры, т.е.Описание и идентификатор.Я хотел бы представить все эти различные классы ГИС с помощью одного общего класса C# (назовем его GisObject), которого достаточно для того, что мне нужно сделать из не-ГИС-части приложения, в которой перечислены ГИС-объекты данной ГИС. сорт.
Проблема для меня заключается в том, как сопоставить эти объекты с помощью NHibernate, чтобы объяснить NHibernate при создании C# GisObject для получения и используйте имя таблицы в качестве параметра который будет прочитан из метатаблицы (это может быть в два этапа: на первом этапе я могу вручную получить имя таблицы, а затем передать его в NHibernate при извлечении данных GisObject).
Кто-нибудь сталкивался с подобной ситуацией и возможно ли это вообще?
Решение 2
@Брайан Чиассон
К сожалению, невозможно создать все классы данных ГИС, поскольку классы создаются в приложении динамически.Все данные ГИС одного типа должны быть классом, но мой пользователь имеет возможность получить новый набор данных и поместить его в базу данных.Я не могу знать заранее, какие классы будут у моего пользователя в приложении.Таким образом, модель сопоставления каждого класса не работает, поскольку завтра появится еще одна новая таблица базы данных и потребуется создать новый класс с новым сопоставлением.
@all может быть возможность написать свой собственный собственный запрос в файле конфигурации XML моего класса Gisobject, затем в классе доступа данных, получая этот запрос, используя
string qs = getSession().getNamedQuery(queryName);
и используйте замену строки, чтобы ввести имя базы данных (путем замены некоторой строки-заполнителя), которую я передам в качестве параметра.
qs = qs.replace(":tablename:", tableName);
Как вы относитесь к такому решению?Я знаю, что это может быть угрозой безопасности в неконтролируемой среде, где имя таблицы будет получено как ввод пользователя, но в этом случае у меня есть метатаблица, содержащая правильные и действительные имена таблиц для классов данных ГИС, которые я прочитаю раньше. вызов запроса на получение данных для определенного класса ГИС-объектов.
Другие советы
Похоже, что проще всего здесь создать абстрактный базовый класс со всеми общими элементами ГИС, а затем наследовать другие X-классы, которые не будут иметь ничего, кроме необходимых сопоставлений NHibernate.Затем я бы использовал шаблон Factory для создания объекта определенного типа, используя ваши метаданные.
Один из способов сделать это — объявить интерфейс, скажем, IGisObject, который имеет общие свойства, объявленные в интерфейсе.Затем реализуйте конкретный класс, который сопоставляется с каждой таблицей.Таким образом, все они по-прежнему будут относиться к типу IGisObject.
Вы можете посмотреть, что говорит Айенде здесь: Многотабличные сущности.
Но поскольку у вас отдельные таблицы, я не думаю, что это сработает.Вы также можете проверить группа nhuser
Думаю, я бы задал вопрос, почему вы собираете данные ГИС непосредственно в базе данных, а не используете тот API, который обычно предоставляется вам в качестве абстракции.Если это система ESRI, есть инструменты, которые позволяют создавать статические представления базы данных в их объектах ГИС, и тогда, возможно, с этого момента это может быть подходящим для извлечения данных.
Из документации NHibernate вы можете использовать один из сопоставления наследования.
У вас также может быть отдельный класс для каждой таблицы, но все они должны реализовывать некий общий интерфейс.