(N)Hibernate - 是不是可以将多个表动态映射到一个类
Posted
技术标签:
【中文标题】(N)Hibernate - 是不是可以将多个表动态映射到一个类【英文标题】:(N)Hibernate - is it possible to dynamically map multiple tables to the one class(N)Hibernate - 是否可以将多个表动态映射到一个类 【发布时间】:2008-09-09 11:34:07 【问题描述】:我有这样的情况,我使用 GIS 软件,它将有关 GIS 对象的信息存储到每个类型/类别的 GIS 对象(道路、河流、建筑物、海洋……)的单独数据库表中,并将元数据表保存在它存储有关类名及其 DB 表的信息。
这些不同类的GIS对象共享一些参数,即描述和ID。我想用一个通用的 C# 类(我们称之为 GisObject)来表示所有这些不同的 GIS 类,这足以满足我需要从应用程序的非 GIS 部分执行的操作,该应用程序列出了给定 GIS 的 GIS 对象类。
我的问题是如何使用 NHibernate 映射这些对象,以便在创建 C# GisObject 以接收和使用表名作为参数时向 NHibernate 解释将从元表中读取的参数(可以分两步,我可以在第一步手动获取表名,然后在拉取 GisObject 数据时将其传递给 NHibernate)。
有没有人处理过这种情况,能做到吗?
【问题讨论】:
【参考方案1】:听起来在这里做的最简单的事情可能是创建一个包含所有常见 GIS 成员的抽象基类,然后继承其他 X 类,这些类只具有必要的 NHibernate 映射。然后,我将使用工厂模式使用您的元数据创建特定类型的对象。
【讨论】:
【参考方案2】:@Brian Chiasson
不幸的是,创建所有 GIS 数据类不是一个选项,因为类是在应用程序中动态创建的。每个相同类型的 GIS 数据都应该是一个类,但是我的用户有可能获取新的数据集并将其放入数据库中。我不知道我的用户将在应用程序中拥有哪些类。因此,前面的每类映射模型不起作用,因为明天将有另一个新的数据库表,并且需要使用新映射创建新类。
@全部 可能有可能在我的 GisObject 类的 XML 配置文件中编写我自己的自定义查询,然后在数据访问类中使用
string qs = getSession().getNamedQuery(queryName);
并使用字符串替换来注入数据库名称(通过替换一些占位符字符串),我将作为参数传递。
qs = qs.replace(":tablename:", tableName);
您对该解决方案有何看法?我知道这在不受控制的环境中可能存在安全风险,其中表名将作为用户输入获取,但在这种情况下,我有一个元表,其中包含我之前将阅读的 GIS 数据类的正确和有效表名调用查询以获取特定类 GIS 对象的数据。
【讨论】:
【参考方案3】:您可以这样做的一种方法是声明一个接口,例如 IGisObject,它具有在接口上声明的公共属性。然后实现一个映射到每个表的具体类。这样一来,它们仍然是 IGisObject 类型。
【讨论】:
表格是由用户动态创建的。当用户获得一类新的数据(即从某个来源获得铁路的集合)并希望在应用程序中输入它时,正在创建新表,我需要一种无需单独映射即可访问新数据的方法新表。【参考方案4】:您可以在这里查看 Ayende 所说的内容:MultiTable Entities。
但由于您有单独的表格,我认为它不会起作用。 您也可以查看nhuser group
【讨论】:
【参考方案5】:我想我会问一个问题,为什么您要直接在数据库中查找 GIS 数据,而不是使用通常作为抽象提供给您的 API。如果这是一个 ESRI 系统,则有一些工具可以让您在其 GIS 对象中创建静态数据库视图,然后也许从那时起它可能适合数据提取。
【讨论】:
我用的是鹰图的api,原因是这个api设计和构建得不好。所以我将非 gis 属性提取到 c# 类中,以便在应用程序中用于下拉列表、清单和类似的东西。对于地图渲染,使用 intergraph 的 api。【参考方案6】:从 NHibernate 文档中,您可以使用 inheritance mappings 之一。
您也可以为每个表设置一个单独的类,但让它们都实现一些通用接口
【讨论】:
以上是关于(N)Hibernate - 是不是可以将多个表动态映射到一个类的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate 在使用查询缓存时执行 N+1 个选择而不是 1 个查询
如何在hibernate.cfg.xml中的主配置文件中配置多个映射文件