6

我对 NHibernate 比较陌生,但在最近的几个程序中一直在使用它,我爱上了它。我遇到了需要将 4-5 个数据库中的数据聚合到一个数据库中的情况。具体来说就是序列号数据。每个数据库都有自己的映射文件,但最终实体都共享相同的基本结构(Serial 类)。

我知道 NHibernate 想要每个类都有一个映射,所以我最初的想法是有一个基本的串行类,然后从它为每个不同的数据库继承并创建一个唯一的映射文件(继承的类将有零内容)。这对于抓取所有数据和填充对象应该很有用。然后我想做的是使用基类映射将这些继承的类(不确定正确的术语是什么)保存到基类表中。

问题是我不知道如何强制 NHIbernate 为对象使用特定的映射文件。使用“session.save()”时,将继承的类转换为基类没有任何作用(它抱怨没有映射)。

有没有办法明确指定要使用的映射?还是我缺少一些 OOP 主体来更具体地将继承的类转换为基类?或者这个想法只是一个坏想法。

我能找到的关于 NHibernate(第 8 章)的所有继承内容似乎并不完全适用于这个函数,但我可能错了(每个具体类的 table-per-concrete-class 看起来可能有用,但我可以'关于 NHibernate 如何计算出要做什么,我完全不了解它)。

4

5 回答 5

4

我不知道这是否会有所帮助,但基本上我不会尝试这样做。

从本质上讲,我认为您可能患有“金锤”综合症:当您拥有一个非常好的锤子(即 Hibernate(我同意您对此的看法;它是一个很棒的工具))时,一切看起来都像钉子。

我通常会尝试简单地拥有一个“手动转换”类,即一个具有构造函数的构造函数,该构造函数为您的各个串行类获取休眠类,并将数据简单地复制到其自己的特定格式;然后 Hibernate 可以使用自己的映射简单地将其序列化到(单个)数据库。

实际上,我认为这是一个更好的解决方案的原因是您有效地尝试做的是在您的课程中进行不对称序列化;即从派生类中的一个数据库读取,写入基类中的另一个数据库。真的没有什么太可怕的,只是它基本上是一个单向的过程。如果您真的想从一个数据库转换到另一个,只需进行转换,然后就可以了。

于 2008-11-12T00:42:46.127 回答
2

这可能会有所帮助;

将 NHibernate 与多个数据库一起使用

来自文章;

介绍

...描述了在 ASP.NET 中使用 NHibernate;它提供了与单个数据库进行通信的指南。 但有时需要同时与多个数据库进行通信。为了让 NHibernate 做到这一点,需要为您将与之通信的每个数据库都存在一个会话工厂。但是,与多个数据库的情况一样,一些数据库很少使用。因此,在实际需要之前不要创建会话工厂可能是个好主意。本文从上一篇 NHibernate 与 ASP.NET 文章离开的地方开始,并描述了这种听起来很简单的方法的实现细节。尽管上一篇文章重点介绍了 ASP.NET,但 ASP.NET 和 .NET 都支持以下建议。

...

使用多个数据库时要做的第一件事是配置正确的通信。为每个数据库创建一个单独的配置文件,将它们全部放入一个中央配置文件夹,然后从 web/app.config 中引用它们。

...

于 2008-11-12T01:15:25.933 回答
0

我不是 100% 确定这会满足我的需要,但我今天在谷歌上发现了这个关于 NHibernate 和匿名类型的搜索:

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

有趣的部分(对我来说,我是新手)是 HQL 选择子句中的“新”关键字。所以我可以做的是使用mappingX从DatabaseX中选择SerialX,并将其传递给SerialY(通用/基本Serial)的构造函数。所以现在我从mappingX/databaseX 生成了SerialY,并且(希望)我可以然后session.save 和NHibernate 将使用mappingY/databaseY。

我喜欢这个的原因只是没有持久化两个具有相同数据的类(我认为!)。这与返回 SerialX 列表、迭代并生成 SerialY 并将其添加到新列表(给出的第一个和最佳答案)之间实际上没有功能区别。

这没有为具有继承的 NHibernate 映射创建有用案例的更普遍的好处,但我认为它会做我想要的有限的事情。

于 2008-11-14T21:23:53.150 回答
0

虽然您确实需要为每个表创建一个映射文件/类,但没有什么能阻止您让所有这些类实现一个通用接口。

然后,您可以将它们全部聚合到应用程序层(即列表)中的单个集合中,其中每个类都实现列表)

如果您希望进行更新,您可能必须编写一些管道来跟踪将其存储在哪个会话下(因为您的目标是多个数据库)。但是这样做的过程将根据您的设置方式而有所不同。

于 2008-11-14T23:01:01.067 回答
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 个映射指向同一个类,因为在任何特定会话中只有一个映射到类关系。

至少我认为是这样(无法测试atm)。

不幸的是,这个特定的案例真的很无聊而且没有用处。在同一领域的不同程序中,我从基类中派生出业务逻辑的特定部分。我不想创建映射文件,因为它只是为了简化一小段代码。无论如何,由于与我的第一个问题相同的原因,我无法使其在 NHibernate 中工作,并且确实使用了 McWafflestix 描述的方法来解决它(因为它很小)。

也就是说我通过谷歌找到了这个:

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

这是完全相同的情况,它似乎(可能)在 NH 2.1+ 中得到解决?我还没有跟进。

(注意:丹,在我的情况下,我从几个数据库中获取,只写给一个。我仍然对你关于接口的建议感兴趣,因为我认为这对于其他情况是个好主意。你会定义映射接口?如果我尝试保存一个实现没有映射定义的接口的类,NHibernate 会使用接口映射吗?或者我是否必须在映射中为每个实现接口映射的类声明空子类?)

于 2008-11-15T01:57:17.777 回答