NHibernate:一个基类,几个映射

时间:2008-11-11 15:40:04

标签: c# nhibernate oop nhibernate-mapping

我对NHibernate相对比较新,但是我已经将它用于最后几个节目并且我很喜欢。我遇到了需要将4-5个数据库中的数据聚合到一个数据库中的情况。具体来说,它是序列号数据。每个数据库都有自己的映射文件,但最终实体都共享相同的基本结构(Serial类)。

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

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

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

关于NHibernate(第8章)我可以找到的所有继承内容似乎都不完全适用于这个函数,但我可能是错的(每个具体类的表看起来可能有用,但是关于NHibernate如何确定要做什么,我无法完全理解它。

5 个答案:

答案 0 :(得分:4)

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

基本上,我认为你可能患有“golder hammer”综合症:当你有一把非常好的锤子(即Hibernate(我和你分享你的看法;这是一个非常有用的工具)),一切看起来像一个钉。

我通常会尝试简单地使用“手动转换”类,即具有构造函数的类,这些构造函数将单独的序列类用于hibernate类,并且只是将数据复制到其自己的特定格式;然后Hibernate可以使用自己的映射将其序列化到(单个)数据库。

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

答案 1 :(得分:2)

这可能会有所帮助;

Using NHibernate with Multiple Databases

来自文章;

  

简介

     

...   用NHibernate描述   ASP.NET;它提供了指导方针   与单个数据库通信。   但有时需要   与多个数据库通信   同时。为NHibernate做   这个,会话工厂需要存在   对于您将成为的每个数据库   与...沟通。但是,正如经常那样   有多个数据库的情况,有些   很少使用数据库。所以   不创造可能是个好主意   会议工厂,直到他们   实际需要。这篇文章捡起来了   以前的NHibernate所在的地方   ASP.NET文章中断并描述   这个的实现细节   听起来很简单的方法。虽然   上一篇文章专注于ASP.NET,   以下建议得到支持   ASP.NET和.NET。

     

...

     

工作时要做的第一件事   有多个数据库是   配置适当的通信。   为每个创建单独的配置文件   数据库,将它们全部放入中心   配置文件夹,然后引用它们   来自web / app.config。

     

...

答案 2 :(得分:0)

我不是百分之百确定这会做我需要的,但今天我发现谷歌搜索NHibernate和匿名类型:

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

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

我喜欢这个的原因就是没有两个持有相同数据的类(我想!)。这与返回SerialX列表之间确实没有功能差异,迭代它并生成SerialY并将其添加到新列表(给出的第一个和最佳答案)。

对于使用继承的NHibernate映射创建有用的案例没有更广泛的好处,但我认为它会做我想要的有限的东西。

答案 3 :(得分:0)

虽然这是真的,你需要为每个表都有一个映射文件/类,没有什么可以阻止你让所有这些类实现一个公共接口。

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

如果您希望进行更新,您可能需要编写一些管道来跟踪存储它的会话(因为您要定位多个数据库)。但这样做的过程将根据您的设置方式而有所不同。

答案 4 :(得分: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作为保存的get和mappingY,因为会话没有被共享,并且映射与会话相关联。所以我可以有2个映射指向同一个类,因为在任何特定的会话中只有一个映射到类关系。

至少我认为就是这种情况(无法测试atm)。

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

那说我通过谷歌找到了这个:

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

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

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

相关问题